《Codeforces Round #696 (Div. 2)》
A:显然保证长度不变是最大的,然后交换1,0,2即可。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; int main() { int ca;ca = read(); while(ca--){ int n;n = read(); string s;cin >> s; string ans = "1"; int pre; for(int i = 0;i < s.size();++i){ if(i == 0){ if(s[i] == '0') pre = 1; else pre = 2; } else{ if(pre == 1){ if(s[i] == '0') ans += "0",pre = 0; else ans += "1",pre = 2; } else if(pre == 0){ ans += "1"; if(s[i] == '0') pre = 1; else pre = 2; } else{//pre = 2 if(s[i] == '0') ans += "1",pre = 1; else ans += "0",pre = 1; } } } cout << ans << "\n"; } // system("pause"); return 0; }
B:对于一个只有四个因子的数,排除1和本身,那么另外两个肯定是要素数。(不然就有因子的因子)
所以我们只需要找到这两个素数即可。二分找到第一个>= 1 + d的素数,第二个就是 >= 这个素数 + d的素数。
至于和最后一个数的差距,肯定 >= d,因为数增长到了很大。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; bool vis[N]; int prime[N],tot = 0; void init(){ for(int i = 2;i < N;++i){ if(!vis[i]){ prime[++tot] = i; } for(int j = 1;j <= tot && prime[j] * i < N;++j){ vis[prime[j] * i] = 1; if(i % prime[j] == 0) break; } } } int main() { init(); int ca;ca = read(); while(ca--){ int d;d = read(); int L = lower_bound(prime + 1,prime + tot + 1,1 + d) - prime; L = prime[L]; int r = lower_bound(prime + 1,prime + tot + 1,L + d) - prime; r = prime[r]; printf("%lld\n",1LL * L * r); } //system("pause"); return 0; }
C:显然可以发现,每次选出的一个数都是剩下的数中的最大的数。
那么第一次选的肯定是最大的数和另一个数。一开始就卡在这里了。
但是其实只要另一个数也固定了,剩下的数就是剩下的最大 和 上一轮的最大 - 剩下的最大。
即剩下的选定局面就固定了,所以我们只需要去枚举和最大的数一开始组成的数对即可。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e6 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; int a[2005]; int main() { int ca;ca = read(); while(ca--){ int n;n = read(); map<int,int> mp; priority_queue<int,vector<int>,less<int> > Q; for(int i = 1;i <= 2 * n;++i) { a[i] = read(); mp[a[i]]++; Q.push(a[i]); } sort(a + 1,a + 2 * n + 1); vector<pii> ans; int tag = 0; for(int i = 1;i < 2 * n;++i){ ans.clear(); ans.push_back(pii{a[i],a[2 * n]}); map<int,int> ma = mp; priority_queue<int,vector<int>,less<int> > T = Q; T.pop(); ma[a[i]]--; ma[a[2 * n]]--; int pre = a[2 * n],f = 0; for(int j = 2;j <= n;++j){ while(ma[T.top()] == 0) T.pop(); int tmp = T.top(); T.pop(); ma[tmp]--; int ta = pre - tmp; if(ma[ta] == 0){ f = 1; break; } ma[ta]--; ans.push_back(pii{tmp,ta}); pre = tmp; } if(f == 0){ tag = 1; break; } } if(tag){ printf("YES\n"); printf("%d\n",ans[0].first + ans[0].second); for(auto v : ans) printf("%d %d\n",v.first,v.second); } else printf("NO\n"); } //system("pause"); return 0; }
D:这题非常优秀。
首先考虑,如果不换位,那么检查是否能的话,就是贪心从左往右,或者从右往左(两者等价)。
如果中间 < 0,或者最后 != 0,就说明不可以。
那么加入换位之后,对于换位的操作,即,i位置如果不满足,那么显然要换i位置。
也就是说,不满足的位置不能超过1处。这样的话肯定无解。
然后我们可以发现,交换i位置 和 i + 1位置,对左右都1 ~ L - 1 和 i + 2 ~ n的合并没有影响。
如果我们考虑普通地交换i 和 i + 1,然后再去检查,那么复杂度为n ^ 2。
所以我们只需要预处理出前后和并剩余的石子然后O(1)检查即可。
即L[i - 1],a[i],a[i + 1],r[i + 2]。
为什么只需要考虑交换i 和 i + 1位置,因为如果不合法,显然是i的左边或者右边不合法。
此时其他的都合法,因为不合法的位置不超过1处,那么此时交换相邻的就不会让其他合法的不合法,且是唯一交换法。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e5 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; LL a[N],n,b[N],L[N],r[N]; bool check(){ for(int i = 1;i <= n;++i) b[i] = a[i]; for(int i = 2;i <= n;++i){ b[i] -= b[i - 1]; if(b[i] < 0) return false; } if(b[n] != 0) return false; return true; } int main() { int ca;ca = read(); while(ca--){ n = read(); memset(L,0,sizeof(L)); memset(r,0,sizeof(r)); for(int i = 1;i <= n;++i) a[i] = read(); L[1] = a[1],r[n] = a[n]; for(int i = 2;i <= n;++i){ if(a[i] < L[i - 1]) L[i] = INF; else L[i] = a[i] - L[i - 1]; } for(int i = n - 1;i >= 1;--i){ if(a[i] < r[i + 1]) r[i] = INF; else r[i] = a[i] - r[i + 1]; } if(check()) printf("YES\n"); else{ bool f = 0; swap(a[1],a[2]); if(check()) f = 1; swap(a[1],a[2]); swap(a[n - 1],a[n]); if(check()) f = 1; swap(a[n - 1],a[n]); for(int i = 2;i <= n - 2;++i){ if(L[i - 1] != INF && r[i + 2] != INF && L[i - 1] <= a[i + 1] && r[i + 2] <= a[i] && a[i + 1] - L[i - 1] == a[i] - r[i + 2]){ f = 1; break; } } printf("%s\n",f ? "YES" : "NO"); } } system("pause"); return 0; }