http://codeforces.com/contest/282
A:水,找到中间的算符,处理就行。
B:
话说比赛的时候竟然没有想法,无语了。给出n对数,ai,bi ; ai + bi = 1000 ,求满足sa表示美对数取a的和与sb每对数取b的和之间的差值的绝对值小于等于500。对于每一对数要么取a,要么取b. 取A同A表示取b用G表示,输出最后的结果如果不存在输出-1
我们只要 贪心的选择,如果选A满足就给sa,如果选b满足就给sb,这样走下来就行。
By E_star, contest: Codeforces Round #173 (Div. 2), problem: (B) Painting Eggs, Accepted, # //#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define inf 0x7f7f7f7f #define M 107 #define N 1000007 using namespace std; int a[N],b[N],ans[N]; int Abs(int x) { if (x >= 0) return x; else return (-x); } int main() { int n; int i,j; while (~scanf("%d",&n)) { for (i = 0; i < n; ++i) { scanf("%d%d",&a[i],&b[i]); } int sa = 0; int sb = 0; for (i = 0; i < n; ++i) { // printf("%d %d\n",sa + a[i] - sb,sa - (sb + b[i])); if (Abs(sa + a[i] - sb) <= 500) { sa += a[i]; ans[i] = 0; } else if (Abs(sa - (sb + b[i])) <= 500) { sb += b[i]; ans[i] = 1; } else { break; } } if (i < n) { printf("-1\n"); } else { for (i = 0; i < n; ++i) { if (ans[i] == 0) printf("A"); else printf("G"); } printf("\n"); } } return 0; }
C:
xor or
1 1 0 1
0 1 1 1
1 0 1 1
0 0 0 0
观察可知, 1 1 组和会减少一个1, 1 0 或 01 组和会增加一个1.我们只需要判断1的个数即可,只要a1 > b1 我们就可以通过 11来减少1 达到b状态, a1 == b1 肯定就想相等了(1与0的个数两个状态时相等的) a1 < b1 我们就可以通过01来增加1达到b状态了。(我们需要注意的是,a1 > b1时,注意b1是否为0 ,因为a1不会变为0个1的状态,同理a1 < b1一样注意0的状态)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define inf 0x7f7f7f7f #define M 107 #define N 1000007 using namespace std; char a[N]; char b[N]; int main() { int i,j; int a1,a0,b1,b0; a1 = a0 = b1 = b0 = 0; scanf("%s%s",a,b); int La = strlen(a); int Lb = strlen(b); if (La != Lb) { printf("NO\n"); } else { for (i = 0; i < La; ++i) { if (a[i] == '0') a0++; else a1++; if (b[i] == '0') b0++; else b1++; } if (a1 == b1) printf("YES\n"); else if (a1 > b1) { if (b1 == 0) printf("NO\n"); else printf("YES\n"); } else if (a1 < b1) { if (a1 == 0) printf("NO\n"); else printf("YES\n"); } } return 0; }
D:
当n == 1时 是巴什博奕
当n == 2时是 威佐夫博奕
当n == 3时是尼姆博弈(这里需要证明一下,对于3堆,同时取每一堆相同的个数,不会影响)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 150 #define N 4100007 using namespace std; int a[4]; int solve(int a,int b) { if (a > b) swap(a,b); int k = b - a; int ak = k*(1 + sqrt(5))/2; if (ak == a) return 0; else return 1; } int main() { int n,i; while (~scanf("%d",&n)) { int flag = 0; for (i = 0; i < n; ++i) scanf("%d",&a[i]); if (n == 1) flag = a[0]; else if (n == 2) flag = solve(a[0],a[1]); else flag = a[0]^a[1]^a[2]; if (flag != 0) printf("BitLGM\n"); else printf("BitAryo\n"); } return 0; }
E:
给出n个数求前P个一会的结果与后q个抑或的结果之间抑或的最大结果。
思路:Trie树 + 贪心
首先我们将所前i个数抑或的结果(二进制)存放到Trie树种,然后枚举后缀,在Trie树上贪心的选择与之抑或最大的值。这里最关键的是题目要求不能存在前缀与后缀相交,但是我们贪心的选择前缀时,确实没有排除相交的可能,但是我们想一想的话,如果存在相交,他们两个在疑惑不久取消了吗,之间相当于没有相交。经典的题目...
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 150 #define N 4100007 using namespace std; struct node { node *next[2]; ll flag; }*head; node H[N]; int h; int n; int bit[44]; ll a[100007]; node *newnode() { node *p = &H[h++]; p->next[0] = NULL; p->next[1] = NULL; p->flag = 0; return p; } void insert(ll no) { int i; CL(bit,0); for (i = 0; i <= 40; ++i) { bit[i] = (1&(no>>i)); } node *p = head; for (i = 40; i >= 0; --i) { if (p->next[bit[i]] == NULL) { p->next[bit[i]] = newnode(); } p = p->next[bit[i]]; } p->flag = no; } ll query(ll no) { int i; CL(bit,0); for (i = 0; i <= 40; ++i) { bit[i] = (1&(no>>i)); } node *p = head; for (i = 40; i >= 0; --i) { if (p->next[bit[i]^1]) p = p->next[bit[i]^1]; else p = p->next[bit[i]]; } return (no^p->flag); } int main() { int i; scanf("%d",&n); h = 0; head = newnode(); ll sum = 0; ll ans = 0; for (i = 0; i < n; ++i) { scanf("%I64d",&a[i]); sum ^= a[i]; insert(sum); ans = max(sum,ans); } sum = 0; for (i = n - 1; i >= 0; --i) { sum ^= a[i]; ans = max(ans,query(sum)); } printf("%I64d\n",ans); return 0; }