Codeforces Round #133 (Div. 2)
这次比赛很爽啊,四题,room leader。Rating 终于过 1500 了。Div. 2 专场的题目貌似要简单一些。 A. Tiling with Hexagons 分成几个平行四边形,再减去相邻平行四边形重合的面积。(ab+bc+c*a-(a+b+c)+1)
B. Forming Teams 这道题有个很强烈的限制条件,每个学生最多有两个敌人。于是分为三种情况,环、链和孤立的点,如果环上的结点数为奇数,这个环上一定有个点要被取下。有偶数个节点的链也可以平分为两份,有奇数个节点的链分完之后只能是某一份多一个,奇数个有奇数个节点的链的结果还是某一份多一个,再考虑孤立的点,所以其实只要考虑环,然后剩下的节点数如果是奇数就去得掉一个。
#include
#include
using namespace std;
int map[105][105];
void addedge(int a, int b)
{
map[a][++map[a][0]] = b;
}
int ans;
int visited[105];
void search(int node, int depth)
{
if (visited[node])
{
if (depth - visited[node] > 1)
{
if ((depth - visited[node]) % 2) ++ans;
return;
}
else return;
}
visited[node] = depth;
for (int i = 1; i <= map[node][0]; i++)
{
search(map[node][i], depth + 1);
}
}
int main()
{
int n, m;
cin >> n >> m;
int a, b;
for (int i = 0; i < m; i++)
{
cin >> a >> b;
addedge(a, b);
addedge(b, a);
}
for (int i = 1; i <= n; i++)
{
if (!visited[i]) search(i, 1);
}
if ((n - ans) % 2) ++ans;
cout << ans << endl;
return 0;
}
C. Hiring Staff 这道题也有非常强的限制条件,(m\leq n) 且 (n \neq 1)。 写写算算就出来答案了。 第一天需要 k 个人,第 n 天需要一个,第 n+1 天需要 k-1 个,若 (m \leq n-1),到此结束。若 (m=n),第 2n 天还需要一个,到此结束。其实如果 m > n,应该是第 in 天一个,第 in+1 天 k-1 个吧,(k \geq2),直到 n+m+1 天为止。
#include
#include
using namespace std;
int a[1000000];
int count = 0;
int n, m, k;
void work()
{
if (k == 1)
{
int i = 1;
while (i < n + m + 1)
{
a[count++] = i;
i += n - 1;
}
}
else
{
for (int i = 0; i < k; i++) a[count++] = 1;
a[count++] = n;
for (int i = 0; i < k - 1; i++) a[count++] = n + 1;
if (m <= n - 1) return;
if (m == n)
{
a[count++] = n * 2;
return;
}
if (m > n)
{
int i = 2 * n;
while (true)
{
if (n + m + 1 >= i) break;
a[count++] = i;
if (n + m + 1 >= i) break;
++i;
a[count++] = i;
i += n - 1;
}
}
}
}
int main()
{
cin >> n >> m >> k;
work();
cout << count << endl;
cout << a[0];
for (int i = 1; i < count; i++) cout << " " << a[i];
cout << endl;
return 0;
}
D. Spider’s Web 这题最难的地方在于读题。对于每个 sector 处理一下就可以了。 每个 sector 可能有 (10^5) 个 bridge,bridge 的总数不超过 (10^5),开数组存不下,只好用 vector 啦。
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010;
int ans = 0;
vector num[MAXN];
void work(int cur, int prev, int next)
{
int pcur = 0, pp = 0, pn = 0;
while (num[prev][pp] < num[cur][pcur] && pp < num[prev].size()) ++pp;
while (num[next][pn] < num[cur][pcur] && pn < num[next].size()) ++pn;
++pcur;
while (pcur < num[cur].size())
{
int oldpp = pp, oldpn = pn;
while (num[prev][pp] < num[cur][pcur] && pp < num[prev].size()) ++pp;
while (num[next][pn] < num[cur][pcur] && pn < num[next].size()) ++pn;
if (pp - oldpp != pn - oldpn) ++ans;
++pcur;
}
}
int main()
{
int n, k, temp;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> k;
for (int j = 0; j < k; j++)
{
cin >> temp;
num[i].push_back(temp);
}
sort(num[i].begin(), num[i].end());
}
for (int i = 2; i < n; i++)
{
work(i, i - 1, i + 1);
}
work(1, n, 2);
work(n, n - 1, 1);
cout << ans << endl;
return 0;
}
comments powered by Disqus