Codeforces Round #374 (Div. 2) ABCDE题解
来源:互联网 发布:网络用语缩写 编辑:程序博客网 时间:2024/05/17 13:45
A. One-dimensional Japanese Crossword
输出连续的B序列的个数及长度。
统计一下就可以了。
#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <string>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;typedef pair<int,int> PII;#define mp make_pair#define pb push_back#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1#define lowbit(x) ((x)&(-(x)))#define bitcnt(x) __builtin_popcount(x)#define bitcntll(x) __builtin_popcountll(x)#define debug puts("-------------");//#pragma comment(linker, "/STACK:1024000000,1024000000")const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;const double ERR = 1e-8;const int MOD = 1e9 + 7;const int MAXN = 1e3 + 50;const int MAXM = 1e4 + 50;int n, m, ans[105];char s[105];int main() {#ifdef LOCAL_NORTH FIN;#endif // LOCAL_NORTH while (~scanf("%d%s", &n, s)) { m = 0; int cnt = 0; for (int i = 0; s[i]; i++) { if (s[i] == 'W') { if (cnt) { ans[m++] = cnt; cnt = 0; } } else cnt++; } if (cnt) ans[m++] = cnt; printf("%d\n", m); for (int i = 0; i < m; i++) printf("%d%c", ans[i], " \n"[i == m - 1]); }#ifdef LOCAL_NORTH cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // LOCAL_NORTH return 0;}
B. Passwords
给出若干个字符串,其中一个是密码。然后按照长度从小到大输入字符串,长度相同则可以按任意顺序输入,每1秒输入一次,连错k次则等5秒。求输入密码所需要的最小及最大时间。
统计出
1.长度小于psw的字符串个数,求出最短时间。
2.长度小于psw的字符串个数+长度等于psw长度且字典序小于psw的字符串个数,求出最大时间。
#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <string>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;typedef pair<int,int> PII;#define mp make_pair#define pb push_back#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1#define lowbit(x) ((x)&(-(x)))#define bitcnt(x) __builtin_popcount(x)#define bitcntll(x) __builtin_popcountll(x)#define debug puts("-------------");//#pragma comment(linker, "/STACK:1024000000,1024000000")const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;const double ERR = 1e-8;const int MOD = 1e9 + 7;const int MAXN = 1e3 + 50;const int MAXM = 1e4 + 50;int n, k;string cor, s[105];int main() {#ifdef LOCAL_NORTH FIN;#endif // LOCAL_NORTH while (cin >> n >> k) { for (int i = 0; i < n; i++) cin >> s[i]; cin >> cor; int cnt1 = 0, cnt2 = 0; for (int i = 0; i < n; i++) { if (s[i].size() < cor.size()) cnt1++; if (s[i].size() < cor.size() || (s[i].size() == cor.size() && s[i] != cor)) cnt2++; } int ans1 = cnt1 / k * 5 + cnt1; int ans2 = cnt2 / k * 5 + cnt2; cout << ans1 + 1 << " " << ans2 + 1 << endl; }#ifdef LOCAL_NORTH cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // LOCAL_NORTH return 0;}
C. Journey
n个点,m条边的DAG,走每条边都需要一定的时间,求在规定时间内从1到n,且途中经过最多的点数,然后打印路径。
这道题我的是O(n^3)的方法,O((n+m)n)的方法可以去看一下其他菊苣的博客。
首先拓扑排序一下,然后按照拓扑序dp,状态转移方程是
if (ans[u][j] + E[l].w <= t) ans[v][j + 1] = min(ans[v][j + 1], ans[u][j] + E[l].w);
其中,E[l]是连接u,v的边,E[l].w为边权。
ans全部初始化为INF,dp之后判断ans[n][i]是否为INF就能知道能否在规定时间内到达n。
然后就是打印路径,从n开始逆向dfs。
#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <string>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;typedef __int64 LL;typedef pair<int,int> PII;#define mp make_pair#define pb push_back#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1#define lowbit(x) ((x)&(-(x)))#define bitcnt(x) __builtin_popcount(x)#define bitcntll(x) __builtin_popcountll(x)#define debug puts("-------------");//#pragma comment(linker, "/STACK:1024000000,1024000000")const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;const double ERR = 1e-8;const int MOD = 1e9 + 7;const int MAXN = 5e3 + 50;const int MAXM = 1e4 + 50;int n, m, t;LL ans[MAXN][MAXN];int c, ttmp[MAXN];bool flag;struct { int u, v, w, nxt;}E[MAXN];int tot, Head[MAXN];int in[MAXN], tp[MAXN];void init() { tot = 0; memset(Head, -1, sizeof(Head)); memset(in, 0, sizeof(in)); memset(ans, 0x3f, sizeof(ans));}void edge_add(int u, int v, int w) { E[tot].u = u; E[tot].v = v; E[tot].w = w; E[tot].nxt = Head[u]; Head[u] = tot++;}void tpsort() { int sz = 0; queue<int> q; for (int i = 1; i <= n; i++) { if (!in[i]) { q.push(i); tp[++sz] = i; } } while (!q.empty()) { int u = q.front(); q.pop(); for (int i = Head[u], v; ~i; i = E[i].nxt) { v = E[i].v; in[v]--; if (!in[v]) { q.push(v); tp[++sz] = v; } } }}void dfs(int cnt, int pos, int ran) { if (flag) return; if (cnt == 1 && pos == 1 && ran == 0) { flag = true; for (int i = 1; i <= c; i++) printf("%d%c", ttmp[i], " \n"[i == c]); return; } for (int i = 0; i < m; i++) { int u = E[i].u, v = E[i].v, w = E[i].w; if (v == pos && ans[v][cnt] - ans[u][cnt - 1] == w) { ttmp[cnt] = pos; dfs(cnt - 1, u, ran - w); } }}int main() {#ifdef LOCAL_NORTH FIN;#endif // LOCAL_NORTH while (~scanf("%d%d%d", &n, &m, &t)) { init(); for (int i = 0, u, v, w; i < m; i++) { scanf("%d%d%d", &u, &v, &w); edge_add(u, v, w); in[v]++; } tpsort(); ans[1][1] = 0; for (int i = 1, u, v; i <= n; i++) { u = tp[i]; for (int j = 1; j <= i; j++) { if (ans[u][j] == INFLL) continue; for (int l = Head[u]; ~l; l = E[l].nxt) { v = E[l].v; if (ans[u][j] + E[l].w <= t) ans[v][j + 1] = min(ans[v][j + 1], ans[u][j] + E[l].w); } } } LL tmp = INFLL; for (int i = n; i >= 1; i--) { if (ans[n][i] != INFLL) { c = i; tmp = ans[n][i]; break; } } printf("%d\n", c); flag = false; ttmp[1] = 1; dfs(c, n, tmp); }#ifdef LOCAL_NORTH cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // LOCAL_NORTH return 0;}
D. Maxim and Array
给出一个序列,要求进行至多k次+x或-x的操作,使得所有元素乘积最小,n、k均为2e5。
首先要知道,在一个正数序列的某一项+x,使得乘积最大,那么这个x需要加在最小的数上。
1)初始序列中有奇数个负数
在不改变符号的情况下,使得所有元素绝对值最大。实现就是把所有数放入优先队列中,每次取最小值,+x,入队。
2)初始序列中有偶数个负数
a)绝对值最大的元素 <= k * t
首先将绝对值最小的符号变号,然后进行与1)相同的操作
b)绝对值最小的元素 > k * t
将绝对值最小的元素 - k * t
#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <string>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;typedef __int64 LL;typedef pair<int,int> PII;#define mp make_pair#define pb push_back#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1#define lowbit(x) ((x)&(-(x)))#define bitcnt(x) __builtin_popcount(x)#define bitcntll(x) __builtin_popcountll(x)#define debug puts("-------------");//#pragma comment(linker, "/STACK:1024000000,1024000000")const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;const double eps = 1e-8;const int MOD = 1e9 + 7;const int MAXN = 2e5 + 50;const int MAXM = 1e4 + 50;int n, k, sgn[MAXN];LL x, num[MAXN];struct node{ int id; LL val; node(int _id, LL _val) {id = _id; val = _val;} bool operator < (const node& _) const {return val > _.val;}};void dec() { priority_queue<node> q; for (int i = 0; i < n; i++) q.push(node(i, num[i])); int cnt = k; while (cnt--) { node t = q.top(); int id = t.id; q.pop(); t.val += x; q.push(t); num[id] = t.val; }}int main() {#ifdef LOCAL_NORTH FIN;#endif // LOCAL_NORTH while (~scanf("%d%d%I64d", &n, &k, &x)) { LL min_abs = INFLL; int neg = 0, min_index; for (int i = 0; i < n; i++) { scanf("%I64d", &num[i]); if (num[i]) sgn[i] = num[i] / abs(num[i]); else sgn[i] = 1; if (num[i] < 0) neg++; if (abs(num[i]) < abs(min_abs)) { min_index = i; min_abs = num[i]; } num[i] = abs(num[i]); } if (neg & 1) { dec(); } else { if (abs(min_abs) < k * x) { sgn[min_index] *= -1; num[min_index] = (abs(min_abs) / x + 1) * x - abs(min_abs); k -= abs(min_abs) / x + 1; dec(); } else if (abs(min_abs) > k * x) { num[min_index] -= k * x; } else num[min_index] = 0; } for (int i = 0; i < n; i++) printf("%I64d%c", sgn[i] * num[i], " \n"[i == n - 1]); }#ifdef LOCAL_NORTH cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // LOCAL_NORTH return 0;}
E. Road to Home
n个区间,人只能在区间内唱歌,每次消耗p时间,一旦停下,需要 t 时间的间隔才能继续唱。求最多能唱多少首歌。
dp。
A[i]表示在区间i的走到右端点时,最多能唱多少首歌。
B[i]表示在唱完A[i]首歌,最靠近0的位置。
输入i个区间的同时,每次找到最靠近 l[i] 的B的下标的前一项c,然后从c到i-1,更新A和B,统计最大的A即可。
#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <string>#include <vector>#include <cctype>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;typedef __int64 LL;typedef pair<int,int> PII;#define mp make_pair#define pb push_back#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1#define lowbit(x) ((x)&(-(x)))#define bitcnt(x) __builtin_popcount(x)#define bitcntll(x) __builtin_popcountll(x)#define debug puts("-------------");//#pragma comment(linker, "/STACK:1024000000,1024000000")const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;const double eps = 1e-8;const int MOD = 1e9 + 7;const int MAXN = 1e5 + 50;const int MAXM = 4e5 + 50;int L, n, p, t;int A[MAXN], B[MAXN];void upd(int i, int a, int b) { if (a > A[i]) { A[i] = a; B[i] = b; } else if (a == A[i] && b < B[i]) { B[i] = b; }}int main() {#ifdef LOCAL_NORTH FIN;#endif // LOCAL_NORTH while (~scanf("%d%d%d%d", &L, &n, &p, &t)) { memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B)); A[0] = 0; B[0] = -t; int l, r, c = 0, ans = 0; for (int i = 1; i <= n; i++) { scanf("%d%d", &l, &r); while (c < i - 1 && B[c] + t < l) c++; if (c) c--; upd(i, A[i - 1], B[i - 1]); for (int j = c; j < i; j++) { if (B[j] + p <= r) { int left = max(l, B[j] + t); int cnt = (r - left) / p; int pos = left + cnt * p; upd(i, A[j] + cnt, pos); } else break; } ans = max(ans, A[i]); } printf("%d\n", ans); }#ifdef LOCAL_NORTH cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // LOCAL_NORTH return 0;}
- Codeforces Round #374 (Div. 2) ABCDE题解
- Codeforces Round #293 (Div. 2) (ABCDE题解)
- Codeforces Round #294 (Div. 2) (ABCDE题解)
- Codeforces Round #296 (Div. 2) (ABCDE题解)
- Codeforces Round #297 (Div. 2) (ABCDE题解)
- Codeforces Round #240 (Div. 2) (ABCDE题解)
- Codeforces Round #313 (Div. 2) (ABCDE题解)
- Codeforces Round #105 (Div. 2) (ABCDE题解)
- Codeforces Round #200 (Div. 2) (ABCDE题解)
- Codeforces Round #186 (Div. 2) (ABCDE题解)
- Codeforces Round #369 (Div. 2) ABCDE题解
- Codeforces Round #361 (Div. 2) ABCDE题解
- Codeforces Round #360 (Div. 2) ABCDE题解
- Codeforces Round #367 (Div. 2) ABCDE 题解
- Codeforces Round #320 (Div. 2) [Bayan Thanks-Round] (ABCDE题解)
- Codeforces Round #198(Div.2)ABCDE
- Codeforces Round #261 (Div. 2)[ABCDE]
- Codeforces Round #264 (Div. 2)[ABCDE]
- C#实现文件下载
- Java对象创建过程
- 浅谈JS中this
- Less学习-语法详解
- 【Java每日一题】20161013
- Codeforces Round #374 (Div. 2) ABCDE题解
- Listit 桌面版开发日志
- uboot之start_armboot分析4
- 构造一个三位数的反序数
- 安卓加载播放网页视频并用百度联盟广告替代屏dan蔽zhu网页部分广告 按返回自动退加到上个网页_源码
- Python将时间字符串00:00:03转化为每天从凌晨算起的秒数
- 诸侯安置 搜索02 empire
- 线性结构4. Pop Sequence(25)
- 旋转数组的最小数字