Codeforces Round #169 (Div. 2)
a. 简单暴力题
b. 简单博弈题,多试试几组数据可以发现性质。
#include <stdio.h> #include <string.h> #include <string> #include <iostream> using namespace std; int main() { char g[1100]; scanf("%s",g); int len=strlen(g); int cnt[30]; int sum=0; memset(cnt,0,sizeof(cnt)); for(int i=0;i<len;i++) { cnt[g[i]-'a']++; } int ans=0; for(int i=0;i<30;i++) { if(cnt[i]%2!=0) ans++; } if(ans==0||ans==1) printf("First\n"); else { if(ans%2==0) printf("Second\n"); else printf("First\n"); } return 0; }
c. 可以用树状数组做,但是最快最好的方法是在用一个数组如果区间 【i-j】 ,就让g[i]++; g[j+1]++ , 然后在从第一个元素到最后一个元素k[i]+=k[i-1]这样迭代;
想想这种方法确实很巧妙.
#include <stdio.h> #include <string.h> #include <algorithm> #include <string> #include <iostream> using namespace std; int g[1001000]; int k[1001000]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&g[i]); for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); k[x]++; k[y+1]--; } for(int i=1;i<=n;i++) { k[i]+=k[i-1]; } sort(g+1,g+n+1); sort(k+1,k+n+1); __int64 sum=0; for(int i=n;i>=1;i--) { sum+=(__int64)g[i]*k[i]; } printf("%I64d",sum); return 0; }
4. 想到了其实也是很简单, 只要找到一个l和r 以二进制表示时的第一个不用的数, 那么后面的就都可以异或得1了。 这样就是最大的数
#include <stdio.h> #include <string.h> #include <string> #include <iostream> using namespace std; typedef __int64 LL; int gl[100],gr[100]; LL fuc(int x) { LL sum=1; for(int i=0;i<x;i++) sum*=2; return sum; } int main() { LL l,r; scanf("%I64d%I64d",&l,&r); LL ans=0; int cnt=0,cnt1=0; LL tmpl=l; LL tmpr=r; while(tmpl>0) { gl[cnt++] = tmpl%2; tmpl/=2; } while(tmpr>0) { gr[cnt1++]=tmpr%2; tmpr/=2; } /*if(cnt1!=cnt) { int tcnt=cnt-cnt1; for(int i=cnt-1;cnt1!=0;i--) { gr[i]=gr[--cnt1]; } for(int i=0;i<tcnt;i++) gr[i]=0; }*/ //int ans[100]; //int tcnt=0; LL sum; ans=0; sum=0; int flag=0; for(int i=cnt1-1;i>=0;i--) { flag=0; LL tmp; tmp=ans+fuc(i); if(!(tmp>r||(tmp+fuc(i)-1)<l)) { flag=1; } tmp=ans; if(!(tmp>r||(tmp+fuc(i)-1)<l)) { if( flag==1 ) { sum+=fuc(i+1)-1; break; } else { continue; } } else { ans+=fuc(i); } } printf("%I64d\n",sum); return 0; }