标签:image 个人 ++ 字符 cpp spl 标记 temp style
题目
A
题意:给四个正整数p,a,b,c 。有三位游泳的人分别在0,a ,2a,3a....;0,b,2b,3b....;0,c,2c,3c.... 的时间来到岸边,另一人将会在P的时间时来到岸边,问p要等多久才能等到至少一个人。
思路:如果p可以整除a,b,c中的某一个则答案为0;否则答案是n -(p%n)的最小值, n为a,b,c。
#include<iostream> typedef long long ll; #define rep(a,n) for(a=1;a<=n;++a) using namespace std; int main() { ios::sync_with_stdio(false); ll p, a, b, c, t; cin >> t; while (t--) { cin >> p >> a >> b >> c; if (p % a == 0 || p % b == 0 || p % c == 0)cout << 0 << endl; else cout << min(min(a - p % a, b - p % b), c - p % c) << endl; } return 0; }
B
题意:只可意会,不可传言(其实是不会,多附一张图
思路:总之我们要让大的尽可能在前面,由于每个数只会用一次,我们可以想办法把用过的数标记下来,同时我们还应该知道每个数在数组的下标,然后从后开始遍历;
#include<iostream> typedef long long ll; #define rep(a,n) for(a=1;a<=n;++a) const ll maxn = 1e5 + 5; using namespace std; int sz[maxn], ans[maxn]; struct p { int index;//储存数在sz数组中的下标 bool us = false;//判断这个数是否被用过 }po[maxn]; int main() { ios::sync_with_stdio(false); ll t, n, i, j, temp; cin >> t; while (t--) { cin >> n; rep(i,n)po[i].us = false; temp = n; int cnt = 0, cou = 0; rep(i,n) { cin >> sz[i]; po[sz[i]].index = i; } for (i = n; i > 0; i--) { if (!po[i].us) { for (j = po[i].index; j <= temp; ++j) { ans[cou++] = sz[j]; po[sz[j]].us = true; } temp = po[i].index - 1;//更新temp } } cout << ans[0]; for (i = 1; i < cou; ++i)cout << " " << ans[i]; cout << endl; } return 0; }
C
题意:两个字符串a,b,其中b是a的子串,求最大的宽度,宽度的定义如题
思路:很容易想到贪心。从前往后遍历一遍,得到可能的情况中b中所有字母都映射在a中的最前面,储存在pre;从后遍历一遍,得到映射在最后面的结果,储存在last中;
随后不断更新,over~
#include<iostream> #include<algorithm> typedef long long ll; #define rep(a,n) for(a=1;a<=n;++a) const ll maxn = 2e5 + 5; using namespace std; char a[maxn], b[maxn]; int pre[maxn], last[maxn]; int main() {
ios::sync_with_stdio(false); int n, m, i, j = 1, ans=0; cin >> n >> m; rep(i, n)cin >> a[i]; rep(i, m)cin >> b[i]; for (i = 1; j <= m && i <= n; ++i) if (a[i] == b[j]) pre[j++] = i; for (i = n,j=m; j > 0 && i > 0; i--)if (a[i] == b[j])last[j--] = i; rep(i, m-1)ans = max(ans, last[i + 1] - pre[i]); cout << ans << endl; return 0; }
D
题意: 构造两个二进制的数,两个数均含有a个0,b个1,它们的差(二进制形式)中含有k个0。PS:所有数中均不可有前导零。
思路:首先特判一下k==0||a==0||b==1的情况,然后考虑一般情况。
对于11xxxxxx0xxx 这样的情况,两者相减等于001111111000 (x为0或者1);这就是构造的方式,除了k>a+b-2的时候我们都可以构造;
10xxxxxx1xxx 代码已经呼之欲出了(虽然但是,写的还是差点心态崩了
#include<iostream> #include<algorithm> typedef long long ll; const ll mod = 1000000007; const ll maxn = 2e5 + 5; const ll inf = 0x3f3f3f3f; using namespace std; int main() { ios::sync_with_stdio(false); ll t, n, i, j, a, temp, k, res, flag, b, c; cin >> a >> b >> k; if (k == 0) { cout << "YES" << endl; for (i = 1; i <= b; ++i)cout << 1; for (i = 1; i <= a; ++i)cout << 0; cout << endl; for (i = 1; i <= b; ++i)cout << 1; for (i = 1; i <= a; ++i)cout << 0; cout << endl; } else { if (a == 0 || b == 1||k>a+b-2)cout << "NO" << endl; else { cout << "YES" << endl; cout << 11; int s0 = a - 1, s1 = b - 2; for (i = 3; i < 2 + k; ++i) { if (s0) { cout << 0; s0--; } else if (s1) { cout << 1; s1--; } } cout << 0; while (1) { if (s0 > 0) { cout << 0; s0--; } else break; } while (1) { if (s1 > 0) { cout << 1; s1--; } else break; } cout << endl; s0 = a - 1, s1 = b - 2; cout << 10; for (i = 3; i < 2 + k; ++i) { if (s0>0) { cout << 0; s0--; } else if (s1 > 0) { cout << 1; s1--; } } cout << 1; while (1) { if (s0 > 0) { cout << 0; s0--; } else break; } while (1) { if (s1 > 0) { cout << 1; s1--; } else break; } cout << endl; } } return 0; }
E 待补;
标签:image 个人 ++ 字符 cpp spl 标记 temp style
原文地址:https://www.cnblogs.com/ggnpgl/p/14443600.html