Codeforces Round #634 (Div. 3)
链接:https://codeforces.com/contest/1335
A - Candies and Two Sisters
略
B - Construct the String
略
C - Two Teams Composing
题意:给n个数,要求找到一个x,使得可以从n个数中先选出一个x个数的无重集合,再选出一个x个相同的数的集合。
题解:统计一下最多的相同的数有几个,记为A1,并且要记录最多的相同的数有几种,记为A2,然后考虑一共有多少种不同的数,记为B。
举几个例子:
1 2 3 4 5 6 3 3 3 3 3 3
1 2 3 4 5 6 3 3 3 3 3 3 3
这种情况,代表A1>=B+1,这种时候受B限制,且可以分A1的一个过去第一个集合,答案是B。
1 2 4 5 6 3 3 3 3 3
1 2 4 5 6 3 3 3 3
这种情况,代表A1<=B-1,这种时候答案是A1。
还差一种情况,A1=B,这种时候是A1-1。
1 2 4 3 3 3 3
D - Anti-Sudoku
题意:给出一个数独,改动其中的至多9个数字,使得其满足:
每行都有至少2个相同元素。
每列都有至少2个相同元素。
分成九宫格的每个格都有至少2个相同元素。
题解:没说要保持数字的总数不变啊?直接把所有的'2'都换成'1'。
char s[15]; void TestCase() { for(int i = 1; i <= 9; ++i) { scanf("%s", s + 1); for(int j = 1; j <= 9; ++j) { if(s[j] == '2') s[j] = '1'; } puts(s + 1); } }
F - Robots on a Grid
题意:给一个格子图,每个格子上面有标有一个方向“上下左右”其中之一,这个方向不会指引越界。这些格子有些是黑格有些是白格,求最多能放多少个机器人,以及最多能放多少个机器人在黑格。机器人被放在格子图上,沿着格子指引的方向同时移动,当两个机器人在某个时刻撞在一个格子上时是非法的放置方法,(但是他们可以撞在格子边界上)。
题解:这个格子图明显是一篇基环树森林,容易知道“最多能放多少个机器人”就是基环树森林的所有的环的的大小。麻烦的在于求“最多能放多少个机器人在黑格”,想到一个好办法,当发现一个基环树的环之后,从这个环上的任意一点开始dfs染色,深度从[1,M]循环,M是这个基环树的环的大小,容易发现染色相同的格子是只能放一个机器人的,这时就判断这些格子中是否有至少一个黑色格就可以了。
int n, m; int id(int i, int j) { return (i - 1) * m + j; } int U(int id) { return id - m; } int D(int id) { return id + m; } int L(int id) { return id - 1; } int R(int id) { return id + 1; } int top; char s[1000005]; int C[1000005]; int G[1000005]; vector<int> BG[1000005]; int color[1000005], cntcolor; vector<int> CurCircle; int incircle; void dfs(int u, int c) { if(color[u]) { if(color[u] == c) { incircle = u; return; } return; } color[u] = c; dfs(G[u], c); if(incircle) { CurCircle.push_back(u); if(u == incircle) incircle = 0; } return; } int ans1, ans2; int CntBlack[1000005], M; int vis[1000005]; void DFS(int u, int dep) { if(vis[u]) return; vis[u] = 1; if(C[u] == 0) { if(CntBlack[dep] == 0) { CntBlack[dep] = 1; ++ans2; } } if(dep == M) dep = 0; for(auto &v : BG[u]) DFS(v, dep + 1); return; } void Solve2() { M = CurCircle.size(); DFS(CurCircle[0], 1); for(int i = 0; i <= M; ++i) CntBlack[i] = 0; } void Solve() { ans1 = 0, ans2 = 0; cntcolor = 0; for(int i = 1; i <= n * m; ++i) { if(!color[i]) { ++cntcolor; CurCircle.clear(); dfs(i, cntcolor); if(CurCircle.size()) { ans1 += CurCircle.size(); Solve2(); } } } printf("%d %d\n", ans1, ans2); } void TestCase() { scanf("%d%d", &n, &m); for(int i = 1; i <= n * m; ++i) { BG[i].clear(); vis[i] = 0; color[i] = 0; } top = 0; for(int i = 1; i <= n; ++i) { scanf("%s", s + 1); for(int j = 1; j <= m; ++j) C[++top] = s[j] - '0'; } top = 0; for(int i = 1; i <= n; ++i) { scanf("%s", s + 1); for(int j = 1; j <= m; ++j) { ++top; if(s[j] == 'U') { G[top] = U(id(i, j)); BG[U(id(i, j))].push_back(id(i, j)); } else if(s[j] == 'D') { G[top] = D(id(i, j)); BG[D(id(i, j))].push_back(id(i, j)); } else if(s[j] == 'L') { G[top] = L(id(i, j)); BG[L(id(i, j))].push_back(id(i, j)); } else if(s[j] == 'R') { G[top] = R(id(i, j)); BG[R(id(i, j))].push_back(id(i, j)); } else exit(-1); } } Solve(); }
先写一个读入这个奇怪的图的程序,然后到我的模板库里面复制一份基环树遍历的算法,由于这里只需要知道基环树的大小,那么只注意“incircle”标记的节点就可以了。注意并不是每次dfs都可以找到一棵新的基环树,有可能这棵基环树被前面的dfs找到过,这个就不细讲了。总而言之没有基环树dp就都还算简单。
- 用div层来实现页面半透明遮罩效果
- DIV+CSS相对IE6、IE7和IE8的兼容问题
- Codeforces Round #167 (Div. 2) A题
- Codeforces Round #161 (Div. 2) D. Cycle in Graph(无向图中找指定长度的简单环)
- Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)
- 328 (Div. 2) B
- Codeforces Round #358 (Div. 2) E 计算几何 旋转卡壳求最大三角形面积
- Codeforces Round #387 (Div. 2)D. Winter Is Coming(优先队列)
- SPOJ - NDIV n-divisors (约数个数问题)
- div设置滚动条
- Div+CSS布局入门教程--写入整体层结构与CSS
- 让几个div靠外面容器底部对齐
- CSS DIV IE6
- Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note
- Codeforces Round #292 (Div. 2)
- Codeforces Round #328 (Div. 2) D. Super M (树的直径,虚树的直径)
- CSS文本和div垂直居中方法总结
- Codeforces Round #387 (Div. 2)A~D A Display Size D Winter Is Coming
- div + css命名规则
- Codeforces Round #202 (Div. 1) B. Apple Tree CF348B