Codeforces Round #418 (Div. 2)
由于所有的数组B内所有的数都不同,因此当k > 1是就可以使该序列不递增
当k = 1是,带入B[0],判断序列A是否递增就可以啦
#include <bits/stdc++.h> using namespace std; const int MAXN = 100008; int a[MAXN], b[MAXN]; int main() { int n, k; scanf("%d%d", &n, &k); for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(int i = 0; i < k; i++) scanf("%d", &b[i]); if(k > 1) return 0*printf("Yes\n"); for(int i = 0; i < n; i++) if(a[i] == 0) a[i] = b[0]; int flag = 1; for(int i = 0; i < n; i++) { if(a[i] < a[i-1]) flag = 0; } if(flag) printf("No\n"); else printf("Yes\n"); return 0; }
根据题意可以判断出最多有两个a[i] != b[i]
所以如果只有一个a[i] != b[i]的时候,此时的解是唯一的
否则 将会有可能是答案的两个数x, y
然后判断输出符合答案的解就好了
显然一定会有解的,题目保证!
#include <bits/stdc++.h> using namespace std; const int MAXN = 100008; int a[MAXN], b[MAXN], p[MAXN], q[MAXN]; int vis[MAXN]; int main() { int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(int i = 0; i < n; i++) scanf("%d", &b[i]); memset(vis, 0, sizeof(vis)); memset(p, 0, sizeof(p)); for(int i = 0; i < n; i++) { if(a[i] == b[i]) { p[i] = a[i]; q[i] = a[i]; vis[a[i]]++; } } int x[3], num = 0; for(int i = 1; i <= n; i++) { if(!vis[i]) { x[num++] = i; } } for(int i = 0; i < n; i++) { if(p[i] == 0) p[i] = x[--num]; } for(int i = 0; i < n; i++) { if(q[i] == 0) q[i] = x[num++]; } int flag1 = 0, flag2 = 0; for(int i = 0; i < n; i++) { if(a[i] != p[i]) flag1++; if(b[i] != p[i]) flag2++; } if(flag1 == 1 && flag2 == 1) for(int i = 0; i < n; i++) printf("%d ", p[i]); else for(int i = 0; i < n; i++) printf("%d ", q[i]); return 0; }
暴力 双指针
大概是3e8,可以过
#include <bits/stdc++.h> using namespace std; const int MAXN = 100008; string s; char change; int main() { int n, Q, x; cin >> n >> s >> Q; while(Q--) { cin >> x >> change; int r = 0, ans = 0, chance = x, res = 0; for(int l = 0; l < n; l++) { while(r < n) { if(s[r] == change) ans++, r++; else { if(chance > 0) { chance--; ans++; r++; } else break; } } res = max(ans, res); if(s[l] == change) ans--; else ans--, chance++; } printf("%d\n", res); } return 0; }
贪心
首先要建树,将每个圆和比它刚好大的圆建立一条边
这个刚比它大的圆是该圆的父亲
对于每棵树,设根的深度为1, 深度 <= 2 的圆是可以分别放的
对于其他的圆, 都放入第一个圆内,即深度为奇则减, 深度为偶则加
想想为什么可以这样贪心
如果存在一棵树为 5->4->3->2->1
第一个图 5->3->2->1
第二个图 4
3这个圆无论放图一还是图二都是要减去它的面积的
2这个圆,放在图一是加上它的面积的,放在图二是要减去的, 当然要放在图1
1这个圆无论放图一还是图二都是要减去它的面积的
如果把2这个圆放在图二,那么1这个圆放在图一,图二都是加上的
但是 S2 > S1, 这个方法比前面的方法显然要亏
当前圆的面积总比后面圆的面积大,我们考虑当前圆的放置就是最优的
#include <bits/stdc++.h> using namespace std; const int MAXN = 1008; struct Cirle{ int x, y, r; bool operator < (const Cirle &o) const { return r < o.r; } }s[MAXN]; bool check(int x, int y) { double xx = s[x].x - s[y].x, yy = s[x].y - s[y].y, gg = s[x].r - s[y].r + 0.001; double len = sqrt(xx*xx + yy*yy); if(gg >= len) return true; return false; } vector<int>G[MAXN]; int vis[MAXN]; double sum = 0; const double pi = acos(-1.0); void dfs(int u, int deep) { vis[u] = 1; if(deep <= 2) sum += 1.0*pi*s[u].r*s[u].r; else if(deep&1) sum -= 1.0*pi*s[u].r*s[u].r; else sum += 1.0*pi*s[u].r*s[u].r; for(auto v: G[u]) dfs(v, deep+1); } int main() { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].r); sort(s+1, s+1+n); for(int i = 1; i <= n; i++) { for(int j = i+1; j <= n; j++) { if(check(j, i)) { G[j].push_back(i); break; } } } for(int i = n; i >= 1; i--) { if(!vis[i]) { dfs(i, 1); } } printf("%.9f\n", sum); return 0; }