Codeforces Round #383 (Div. 2)
来源:互联网 发布:剑三毒哥妖孽捏脸数据 编辑:程序博客网 时间:2024/05/17 05:01
A. Arpa’s hard exam and Mehrdad’s naive cheat
找规律即可。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int main(){ int n; while(scanf("%d", &n) != EOF){ if(n == 0){ printf("1\n"); continue; } if(n%4 == 1) printf("8\n"); else if(n%4 == 2) printf("4\n"); else if(n%4 == 3) printf("2\n"); else if(n%4 == 0) printf("6\n"); } return 0;}
B - Arpa’s obvious problem and Mehrdad’s terrible solution
这道题主要就是利用异或的性质,如果A^B = C,那么C^B = A,那么直接排序二分即可。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e5+100;#define LL long longint a[maxn];int main(){ int n, x; while(scanf("%d%d", &n, &x) != EOF){ for(int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a+1, a+n+1); LL ans = 0; for(int i = 1; i <= n; i++){ int temp = x^a[i]; int l1 = i+1, r1 = n; while(l1 < r1){ int mid = (l1+r1)/2; if(a[mid] >= temp) r1 = mid; else l1 = mid+1; } int l2 = i+1, r2 = n; while(l2 < r2){ int mid = (l2+r2+1)/2; if(a[mid] <= temp) l2 = mid; else r2 = mid-1; } // printf("l = %d\n", r1); // printf("r = %d\n", l2); if(a[r1] == temp && a[l2] == temp)ans += (LL)l2-r1+1; } printf("%I64d\n", ans); } return 0;}
C - Arpa’s loud Owf and Mehrdad’s evil plan
并查集瞎搞,因为每一个点只可能包含在一个环中,因为每个点的出度为1,因此,如果一个点的度数是奇数那么直接输出-1即可,然后对于奇偶环判断即可,然后找到这些奇偶环中的点数,求最小公倍数即可,但是因为偶数环只用跑一遍就可以了,所以为偶数是要除以2。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 105;#define LL long longint fa[maxn], sum[maxn], degree[maxn];LL gcd(LL a, LL b){ return !b?a:gcd(b, a%b);}int Find(int x){ if(x == fa[x]) return fa[x]; fa[x] = Find(fa[x]); return fa[x];}void Merge(int from, int to){ int x = Find(from); int y = Find(to); if(x != y){ fa[x] = y; sum[y] += sum[x]; }}void init(){ memset(degree, 0, sizeof(degree)); for(int i = 0; i < maxn; i++) fa[i] = i, sum[i] = 1;}int main(){ int n, to; while(scanf("%d", &n) != EOF){ init(); for(int from = 1; from <= n; from++){ scanf("%d", &to); degree[from]++; degree[to]++; Merge(from, to); } for(int i = 1; i <= n; i++) if(degree[i]&1){ printf("-1\n"); return 0; } LL t = 1; for(int i = 1; i <= n; i++) if(fa[i] == i){ if(sum[i]&1) t = t*sum[i]/gcd(t, sum[i]); else t = t*sum[i]/2/gcd(t, sum[i]/2); } printf("%I64d\n", t); } return 0;}
D. Arpa’s weak amphitheater and Mehrdad’s valuable Hoses
并查集加分组背包即可,先用并查集跑出所有的组数,每组中需要加上一个物品,该物品就是所有物品的w值和b值之和,然后跑分组背包即可,因为如果加上组数,那么dp数组空间达到了1e9,因此我直接利用了滚动数组进行优化,跑一边可过。
#include <map>#include <set>#include <cstdio>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1050;struct Node{ int w, b; Node(){} Node(int _w, int _b):w(_w), b(_b){}};vector <Node> vec[maxn];int w[maxn], b[maxn], fa[maxn];int dp[maxn*maxn];int Find(int x){ if(x == fa[x]) return x; fa[x] = Find(fa[x]); return fa[x];}void Merge(int l, int r){ int x = Find(l); int y = Find(r); if(x != y) fa[x] = y;}void init(){ for(int i = 0; i < maxn; i++) fa[i] = i, vec[i].clear();}int main(){ int N, M, W; while(scanf("%d%d%d", &N, &M, &W) != EOF){ init(); for(int i = 1; i <= N; i++) scanf("%d", &w[i]); for(int i = 1; i <= N; i++) scanf("%d", &b[i]); int l, r; for(int i = 0; i < M; i++){ scanf("%d%d", &l, &r); Merge(l, r); } int cnt = 0; map <int, int> Map; for(int i = 1; i <= N; i++){ if(Map[Find(i)]) vec[Map[Find(i)]].push_back(Node(w[i], b[i])); else{ Map[Find(i)] = ++cnt; vec[cnt].push_back(Node(w[i], b[i])); } } for(int i = 1; i <= cnt; i++){ int xx = 0, yy = 0; for(int j = 0; j < vec[i].size(); j++){ xx += vec[i][j].w; yy += vec[i][j].b; } vec[i].push_back(Node(xx, yy)); // printf("xx = %d, yy = %d\n", xx, yy); } memset(dp, 0, sizeof(dp)); for(int i = 1; i <= cnt; i++) for(int j = W; j >= 0; j--) for(int k = 0; k < vec[i].size(); k++) if(j >= vec[i][k].w) dp[j] = max(dp[j], dp[j-vec[i][k].w] + vec[i][k].b); printf("%d\n", dp[W]); } return 0;}
E. Arpa’s overnight party and Mehrdad’s silent entering
想通了这道题,这道题构造的地方就是2*i-1和2*i连边,首先这样保证了任意三个相邻的不可能有同一种食物,那么这种构造为什么对呢,首先这样处理之后可以保证每个点的入度等于出度等于2,如果相邻2个点正好是男女朋友,那么这样处理之后一定还是二分图,如果不是,因为每个点入度出度都为2,因此每个点必定是环里的一点,又因为环中的边一定是男女朋友边和相邻边交替进行的,所以一定有偶数条,那么这样一来还是二分图,所以证明成立。然后直接黑白染色即可。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2e5+100;struct Edge{ int to, next;}e[maxn<<2];int head[maxn], color[maxn], l[maxn], r[maxn], tot;void addedge(int from, int to){ e[tot].to = to; e[tot].next = head[from]; head[from] = tot++;}void dfs(int u, int c){ color[u] = c; for(int i = head[u]; i != -1; i = e[i].next){ int v = e[i].to; if(color[v] == -1) dfs(v, 1-c); }}void init(){ memset(head, -1, sizeof(head)); memset(color, -1, sizeof(color)); tot = 0;}int main(){ int n; while(scanf("%d", &n) != EOF){ init(); for(int i = 1; i <= n; i++){ scanf("%d%d", &l[i], &r[i]); addedge(l[i], r[i]); addedge(r[i], l[i]); addedge(2*i-1 , 2*i); addedge(2*i, 2*i-1); } for(int i = 1; i <= 2*n; i++) if(color[i] == -1) dfs(i, 0); for(int i = 1; i <= n; i++) printf("%d %d\n", color[l[i]]+1, color[r[i]]+1); } return 0;}
1 0
- Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)(A+B)
- Codeforces Round #383 (Div. 2) B
- Codeforces Round #383 (Div. 2) A
- 【解题报告】Codeforces Round #383 (Div. 2)
- Codeforces Round #383 (Div. 2)ABC
- Codeforces Round #383 (Div. 2) 题解
- codeforces Round #383 (Div.2) C
- Codeforces Round #383 (Div. 2) A
- Codeforces Round #383 (Div. 2) B
- Codeforces Round #383 (Div. 2) D
- Codeforces Round #383 (Div. 1)
- Codeforces Round #102 (Div. 2)
- Codeforces Round #103 (Div. 2)
- 监控SQL:用触发器来监控是哪些语句、存储过程修改了特定表(4)
- 最短路SPFA算法模板
- 【git】git简介及安装
- MAC下安装DroidBox
- study-18:LN(ginx)MP组合
- Codeforces Round #383 (Div. 2)
- 【git】相关学习网址
- MySQL数据文件替换升级
- Nginx开发一个简单的HTTP过滤模块
- ubuntu16.04安装wine和QQ教程
- 红帽RHEL7版本RHCE认证学习及考试经历
- 项目架构DDD
- GitHub上传项目
- docker registry部署