AtCoder Grand Contest 039
October 29, 2019
老刷水题也没有意思,难的题又做不出来,只能捡些题来做,果然菜是原罪。
A. Connection and Disconnection
单独考虑全是一种字母的情况。
如果不是,就把每个字符串分成三段,前中后,如果前和后一样,再另行计算。细节较多,慢慢写不难。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <vector> #include <queue> #include <functional> #include <map> #define M 605 using namespace std; int main() { string s; long long k, front, beh, beh_num = 0; cin >> s; cin >> k; front = 0, beh = s.size() - 1; for (long long i = 1; i < s.size(); i++) if (s[i] != s[i - 1]) { front = i; break; } for (long long i = s.size() - 1; i >= 1; i--) if (s[i - 1] != s[i]) { beh_num = s.size() - i; beh = i; break; } if (front == 0 || beh_num == 0) { cout << k*s.size() / 2 << endl; return 0; } long long tot = 0; tot += front / 2; tot += beh_num / 2; long long mid = 0; for (long long i = front; i < beh; i++) { long long num = 1; while (1) { if (s[i] == s[i + num]) num++; else break; } mid += num / 2; i = i + num - 1; } if (s[0] == s[s.size() - 1]) tot += (k - 1)*((front + beh_num) / 2) + k * mid; else tot = tot * k + k * mid; cout << tot << endl; return 0; }
B. Graph Partition
所有下标为奇数的集合里的点必两两不相邻,偶数同理,故满足条件的无向图必为二分图,所以可用bfs染色的方法判断。之后观察到集合的数量不可能超过图的直径+1,假设直径起点为s,终点为t,把距离s距离为i的放在第i+1个集合,必然满足条件,因此最终的答案就是图的直径+1,跑一遍floyd求最大值就行。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <vector> #include <queue> #include <functional> #include <map> #define M 605 int dis[M][M], color[M]; using namespace std; bool bfs(int s, int n) { queue<int> q; q.push(s); color[s] = 1; while (!q.empty()) { int from = q.front(); q.pop(); for (int i = 1; i <= n; i++) { if (dis[from][i] != (int)1e9 && color[i] == -1) { q.push(i); color[i] = !color[from]; //染成不同的颜色 } if (dis[from][i] != (int)1e9 && color[from] == color[i]) //颜色有相同,则不是二分图 return false; } } return true; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { string s; cin >> s; for (int j = 0; j < n; j++) { if (s[j] == '1') dis[i][j + 1] = 1; else dis[i][j + 1] = (int)1e9; } } memset(color, -1, sizeof(color)); bool flag = false; for (int i = 1; i <= n; i++) if (color[i] == -1 && !bfs(i, n)) { cout << -1 << endl; return 0; } for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); int maxl = -1; for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) { if (dis[i][j] == 1e9) { cout << -1 << endl; return 0; } maxl = max(maxl, dis[i][j]); } cout << maxl + 1 << endl; return 0; }
感觉AGC能做出前两道就不错了,ABC保4争5,AGC保1争2?
剩下的题还没看,听说很难,就这样吧。