Educational Codeforces Round 27 补题
题目链接:http://codeforces.com/contest/845
A. Chess Tourney
水题,排序之后判断第n个元素和n+1个元素是不是想等就可以了。
#include <bits/stdc++.h> using namespace std; int a[210]; int n; int main() { scanf("%d", &n); for(int i=1; i<=2*n; i++) scanf("%d", &a[i]); sort(a+1,a+2*n+1,greater<int>()); if(a[n]!=a[n+1]) puts("YES"); else puts("NO"); return 0; }
B. Luba And The Ticket
题意:给了一个只有6个字母的字符串,然后问最少改变几个数字,使得前3个数字的和等于后3个数字的和。
解法:直接暴力枚举这6位数字会变成什么,在满足条件下维护最小值。
#include <bits/stdc++.h> using namespace std; int a[10]; char s[10]; int main() { scanf("%s", s+1); for(int i=1; i<=6; i++){ a[i] = s[i]-'0'; } int ans = 100; for(int i=0; i<10; i++){ for(int j=0; j<10; j++){ for(int k=0; k<10; k++){ for(int x=0; x<10; x++){ for(int y=0; y<10; y++){ for(int z=0; z<10; z++){ if(i+j+k==x+y+z){ int cnt = 0; if(i!=a[1]) cnt++; if(j!=a[2]) cnt++; if(k!=a[3]) cnt++; if(x!=a[4]) cnt++; if(y!=a[5]) cnt++; if(z!=a[6]) cnt++; ans = min(ans, cnt); } } } } } } } printf("%d\n", ans); }
C. Two TVs
题意:有n个电视节目,每个节目有一个开始的播放时间和结束的播放时间,现在有2台电视可以同时播放节目,但是有重合时间点的节目不能在同一台电视播放,问是否可以通过安排播放顺序让所有的节目都被播放完。
解法:一个显然的贪心,按l,r从小到大排序之后,分别往第一个和第二个电视结束时间最早的那个放就OK了。
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5+5; struct node{ int l,r; node(){} bool operator<(const node &rhs) const{ if(l == rhs.l) return r<rhs.r; return l<rhs.l; } }a[maxn]; int en1, en2; int main() { int n; scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d %d", &a[i].l,&a[i].r); } sort(a+1,a+n+1); en1 = -1, en2 = -1; for(int i=1; i<=n; i++){ if(a[i].l > en1 && a[i].l > en2){ if(en1 > en2){ en2 = a[i].r; } else{ en1 = a[i].r; } } else if(a[i].l > en1){ en1 = a[i].r; } else if(a[i].l > en2){ en2 = a[i].r; } else{ puts("NO"); return 0; } } puts("YES"); return 0; }
D. Driving Test
题意:给出n次操作,你可以忽略 可以超车,不可以超车,速度最大限制以及无速度限制这些操作,问使得超车以及改变速度合法的前提下最少需要忽略多少次操作,每次超车可以覆盖前面所有的超车和不超车,速度最大限制和无速度限制一样。
解法:直接模拟即可。
#include <bits/stdc++.h> using namespace std; int main() { int n,op,x,now=0,lim=0,cnt=0; vector<int>v; scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d", &op); if(op == 1){ scanf("%d", &x); now=x; while(!v.empty() && now>v.back()){ v.pop_back(); cnt++; } } if(op == 2){ cnt += lim; lim = 0; } if(op == 3){ scanf("%d", &x); v.push_back(x); while(!v.empty() && now>v.back()){ v.pop_back(); cnt++; } } if(op == 4){ lim = 0; } if(op == 5){ v.clear(); } if(op == 6){ lim++; } } printf("%d\n", cnt); return 0; }
E:
F:
G. Shortest Path Problem?
题意:这道题要求从1到n的最小xor和路径,存在重边,允许经过重复点、重复边。
解法:线形基,BZOJ原题,BZOJ 2115 不过那道题求的是最大值,这个题求的是最小值。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 100010; const int maxm = 500010; int n, m, edgecnt; int head[maxn]; bool vis[maxn]; LL dx[maxn]; LL p[70]; LL circle[maxm], ans; void init(){ memset(head, -1, sizeof(head)); edgecnt = 0; } struct edge{ int to,next; LL w; edge(){} edge(int to, int next, LL w):to(to),next(next),w(w){} }E[maxm]; int cnt = 0; void add(int u, int v, LL w){ E[edgecnt].to = v, E[edgecnt].next = head[u], E[edgecnt].w = w, head[u] = edgecnt++; } void dfsloop(int x){ vis[x] = 1; for(int i=head[x]; i+1; i=E[i].next){ int to = E[i].to; if(!vis[to]) dx[to] = dx[x]^E[i].w, dfsloop(to); else{ circle[++cnt] = dx[to]^dx[x]^E[i].w; } } } int main() { int x,y; LL z; init(); scanf("%d %d", &n,&m); for(int i=1; i<=m; i++){ scanf("%d %d %lld", &x,&y,&z); add(x, y, z); add(y, x, z); } dfsloop(1); ans = dx[n];//任取一条从1到n的路径,并得到其xor和 for(int i=1; i<=cnt; i++){ for(int j=62; j>=0; j--){ if(!(circle[i]>>j)) continue; if(!p[j]){ p[j] = circle[i]; break; } circle[i] ^= p[j]; } } //for(int i=62;i>=0;i--) if(!(ans>>i)) ans^=p[i]; //ans有初值,不能直接根据这一位是否为0来判断是否更大,max更为稳妥 for(int i=62; i>=0; i--){ if((ans^p[i])<ans){ ans = ans^p[i]; } } printf("%lld\n", ans); return 0; }