【解题报告】Codeforces Round #302 (Div. 2)
来源:互联网 发布:js frame属性 编辑:程序博客网 时间:2024/06/15 19:06
题目链接
A.Set of Strings(Codeforces 544A)
思路
显然,若字符串中有不少于
代码
#include <bits/stdc++.h>using namespace std;int k, vis[30];string s, sub;vector <int> v;int main() { cin >> k >> s; for(int i = 0; i < s.size(); i++) { if(vis[s[i]-'a'] == 0) { vis[s[i]-'a'] = 1; v.push_back(i); } } if(v.size() < k) puts("NO"); else { puts("YES"); for(int i = 0; i < k; i++) { if(i != k - 1) sub = s.substr(v[i], v[i+1] - v[i]); else sub = s.substr(v[i], s.size() - v[i]); cout << sub << endl; } } return 0;}
B.Sea and Islands(Codeforces 544B)
思路
这是一道构造的题目。由于是构造,所以只需要找到构造的特例就行。首先,由国际象棋的棋盘可以联想到,
代码
#include <cstdio>int n, k;int main() { scanf("%d%d", &n, &k); if(2 * k - 1 > n * n) { puts("NO"); } else { puts("YES"); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(k > 0 && ((i ^ j) & 1) == 0) { putchar('L'); k--; } else { putchar('S'); } } puts(""); } } return 0;}
C.Writing Code(Codeforces 544C)
思路
这种有一定资源限制求最优解或解的数量,或者说在每种状态下有超过一种的决策方案,但是不同的决策向量的子结构能转移到同一个状态的问题,通常能用动态规划解决。更具体地,通常能用背包思想解决。因为显然程序员i写的单行代码就是背包问题中的物品
代码
#include <bits/stdc++.h>using namespace std;const int maxn = 505;int n, m, b, mod, ans, a[maxn], d[maxn][maxn];int main() { scanf("%d%d%d%d", &n, &m, &b, &mod); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } d[0][0] = 1; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { for(int k = a[i]; k <= b; k++) { d[j][k] = (d[j][k] + d[j-1][k-a[i]]) % mod; } } } for(int k = 0; k <= b; k++) { ans = (ans + d[m][k]) % mod; } printf("%d\n", ans); return 0;}
D.Destroying Roads(Codeforces 544D)
思路
若不考虑路径重合的话,
代码
#include <bits/stdc++.h>using namespace std;const int maxn = 3010;bool vis[maxn];int n, m, u, v, s1, t1, l1, s2, t2, l2, tmp, ans;int d[maxn][maxn];vector <int> G[maxn];void bfs(int s) { queue <int> q; q.push(s); vis[s] = true; d[s][s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(vis[v] == true) { continue; } d[s][v] = d[s][u] + 1; q.push(v); vis[v] = true; } }}int main() { scanf("%d%d", &n , &m); for(int i = 1; i <= m; i++) { scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } scanf("%d%d%d", &s1, &t1, &l1); scanf("%d%d%d", &s2, &t2, &l2); for(int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); bfs(i); } if(d[s1][t1] > l1 || d[s2][t2] > l2) { puts("-1"); return 0; } ans = d[s1][t1] + d[s2][t2]; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(d[s1][i] + d[i][j] + d[j][t1] > l1) { continue; } tmp = d[i][j] + d[s1][i] + d[j][t1]; if(d[s2][i] + d[i][j] + d[j][t2] <= l2) { ans = min(ans, tmp + d[s2][i] + d[j][t2]); } if(d[s2][j] + d[i][j] + d[i][t2] <= l2) { ans = min(ans, tmp + d[s2][j] + d[i][t2]); } } } printf("%d\n", m - ans); return 0;}
E.Remembering Strings(Codeforces 544E)
思路
这是一个从初始状态经过一系列操作得到目标状态,求最优解的问题。这样的问题适合用搜索或者动态规划解决。由于数据规模的原因,因此不能用搜索解决。分析问题后容易知道,因为行数的上限是20,而小写字母有26个,所以当某行不满足条件时总能通过将该行某列的字符改成别的字符或者将其它行某列的与该行该列相同的字符全部改成其它字符来使该行满足条件而不影响其他行。由于既不能搜索又不能贪心,而且数据量不是很大,所以直接将每行是否满足条件用1和0表示,于是能用一个二进制数表示所有行的状态,进行状态压缩的动态规划。
代码
#include <bits/stdc++.h>using namespace std;const int maxn = 20 + 1, INF = 1e9;char s[maxn][maxn];int n, m, Max, nn, x, y;int d[1<<maxn], a[maxn][maxn], b[maxn][maxn], same[maxn][maxn];int main() { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%s", s[i]); } for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { scanf("%d", &a[i][j]); } } // 预处理出b和same for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { Max = 0; // 该列有多少与该字符相同的字符 for(int k = 0; k < n; k++) { if(s[i][j] != s[k][j]) { continue; } // 将相同字符的位置信息记录下来 same[i][j] |= (1 << k); Max = max(Max, a[k][j]); b[i][j] += a[k][j]; } b[i][j] -= Max; } } nn = 1 << n; fill(d, d + nn, INF); d[0] = 0; for(int i = 0; i < nn; i++) { // 查找一个不满足条件的行 for(int j = 0; j < n; j++) { x = 1 << j; if(x & i) { continue; } // 查找一个要修改的列 for(int k = 0; k < m; k++) { int y = same[j][k]; d[i|x] = min(d[i|x], d[i] + a[j][k]); d[i|y] = min(d[i|y], d[i] + b[j][k]); } break; } } printf("%d\n", d[nn-1]); return 0;}
- 【解题报告】Codeforces Round #302 (Div. 2)
- Codeforces Round #149 (Div. 2)解题报告
- Codeforces Round #180 (Div. 2) 解题报告
- Codeforces Round #190 (Div. 2) 解题报告
- Codeforces Round #191 (Div. 2) 解题报告
- Codeforces Round #189 (Div. 2) 解题报告
- Codeforces Round #142 (Div. 2) 解题报告
- Codeforces Round #229 (Div. 2) 解题报告
- Codeforces Round #241 (Div. 2) 解题报告
- Codeforces Round #262 (Div. 2)解题报告
- Codeforces Round #267 (Div. 2) 解题报告
- Codeforces Round #266 (Div. 2)解题报告
- Codeforces Round #268 (Div. 2) 解题报告
- Codeforces Round #271 (Div. 2) 解题报告
- Codeforces Round #274 (Div. 2) 解题报告
- Codeforces Round #276 (Div. 2) 解题报告
- Codeforces Round #277 (Div. 2) 解题报告
- Codeforces Round #224 (Div. 2)解题报告
- 飛飛(六十一)模板类实例(各种排序)
- 密钥远程登录与scp
- CodeForces 659 A. Round House(简单数学推理)
- 韦东山u-boot、kernel打补丁操作
- ( Leetcode 110 ) Balanced Binary Tree
- 【解题报告】Codeforces Round #302 (Div. 2)
- objective-C 编程全解-第08章 类NSObject和运行时系统 下
- Android热补丁动态更新实践
- C++11新特性
- 用java原生接口Serializable实现对单例对象的序列化
- OpenGL ES 模拟器
- Codeforces #2 A Winner
- 如何系统地练字?
- linux下无法打开桌面的解决方法