Educational Codeforces Round 70 (Rated for Div. 2)
A. You Are Given Two Binary Strings...
注意到乘以一个\(2^k\)就相当于将二进制左移\(k\)位,然后贪心匹配就行了:找到\(t\)串最后一个\(1\)的位置,然后尽可能地去匹配\(s\)串后面的\(1\)。Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; int T; char s[N], t[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> T; while(T--) { cin >> s + 1 >> t + 1; int n = strlen(s + 1), m = strlen(t + 1); int p = 1; for(int i = m; i >= 0; i--) { if(t[i] == '1') break; p++; } int ans = 0; for(int i = n - p + 1; i >= 0; i--) { if(s[i] == '1') break; ans++; } cout << ans << '\n'; } return 0; }
B. You Are Given a Decimal String...
\(bfs\)预处理出\(d[i][j][k][t]\),即用\([i,j]\)生成器,从数字\(k\)到\(t\)的最小步数即可。Code
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 10, M = 2e6 + 5; int d[N][N][N][N]; bool vis[N]; char s[M]; void bfs(int x, int y, int z, int *d) { memset(vis, 0, sizeof(vis)); queue <int> q; q.push(z); d[z] = 0; if(x > y) swap(x, y); while(!q.empty()) { int u = q.front(); q.pop(); int v1 = u + y, v2 = u + x; if(v1 >= 10) v1 -= 10; if(v2 >= 10) v2 -= 10; if(!vis[v1]) { d[v1] = d[u] + 1; q.push(v1); vis[v1] = 1; } if(!vis[v2]) { d[v2] = d[u] + 1; q.push(v2); vis[v2] = 1; } } } void pre() { //k->t memset(d, -1, sizeof(d)); for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { for(int k = 0; k < 10; k++) bfs(i, j, k, d[i][j][k]); } } // cout << d[0][0][0][0]; } int main() { ios::sync_with_stdio(false); cin.tie(0); pre(); cin >> s + 1; int n = strlen(s + 1); for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { int ans = 0; for(int k = 2; k <= n; k++) { if(d[i][j][s[k - 1] - '0'][s[k] - '0'] == -1) { ans = -1; break; } ans += d[i][j][s[k - 1] - '0'][s[k] - '0'] - 1; } cout << ans << ' '; } cout << '\n'; } return 0; }
C. You Are Given a WASD-string...
\(W,S\)和\(A,D\)是独立的,所以我们可以分开考虑。
现在只考虑\(S,W\)这种情况,模拟一下会发现我们可以将区间向下减少\(1\),当且仅当存在一个\(pos\),满足\(pos>maxpos_{up}\)且\(pos<minpos_{down}\),此时我们在\(pos\)处插入一个\(W\)即可;其它情况也类似。
写起来的话这样写有点麻烦,可以直接找满足条件的数量关系。详见代码吧:Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 5; int T; char s[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> T; while(T--) { cin >> s + 1; int nowx = 0, nowy = 0; int up = 0, down = 0, left = 0, right = 0; int dup = 0, ddown = 0, dleft = 0, dright = 0; int n = strlen(s + 1); for(int i = 1; i <= n; i++) { if(s[i] == 'D') nowy++; if(s[i] == 'W') nowx--; if(s[i] == 'A') nowy--; if(s[i] == 'S') nowx++; up = min(up, nowx); down = max(down, nowx); right = max(right, nowy); left = min(left, nowy); dup = max(dup, nowx - up); ddown = max(ddown, down - nowx); dleft = max(dleft, nowy - left); dright = max(dright, right - nowy); } int x = down - up + 1, y = right - left + 1; ll ans = 1ll * x * y; if(dup != ddown) ans = min(ans, 1ll * max(x - 1, 2) * y); if(dleft != dright) ans = min(ans, 1ll * x * max(y - 1, 2)); cout << ans << '\n'; } return 0; }
D. Print a 1337-string...
构造题。
先构造出1337,然后考虑在后面加若干个3,最后再加一个7。假设3的个数为\(x\),那么现在的答案就为\(C(x,2)+1\)。
我们选择尽量大的\(x\),满足\(C(x,2)+1\leq n_i\)。
最后还会差一点,补一些7在1337后面就行了。
可以证明这样是符合题目限制条件的,只是卡得可能有点紧。Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; int T; int n; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> T; while(T--) { cin >> n; if(n == 1) { cout << "1337" << '\n'; continue; } int x = 2; while(1ll * (x + 1) * x <= 2 * n - 2) x++; cout << "1337"; ll tot = 1ll * x * (x - 1) / 2 + 1; n -= tot; for(int i = 1; i <= n; i++) cout << '7'; for(int i = 3; i <= x; i++) cout << '3'; cout << '7' << '\n'; } return 0; }
E. You Are Given Some Strings...
待补。