標籤:blog http os io 2014 for art re
http://blog.csdn.net/rowanhaoa/article/details/38116713
A:Game With Sticks
水題。。。每次操作,都會拿走一個橫行,一個豎行。
所以一共會操作min(橫行,豎行)次。
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<map>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define mem(a,b) (memset(a),b,sizeof(a))#define lmin 1#define rmax n#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1#define root lmin,rmax,1#define now l,r,rt#define int_now int l,int r,int rt#define INF 99999999#define LL __int64#define mod 1000000009#define eps 1e-6#define zero(x) (fabs(x)<eps?0:x)#define maxn 330000int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { int y=min(n,m); if(y%2)cout<<"Akshat"<<endl; else cout<<"Malvika"<<endl; } return 0;}
B:Sort the Array
給數組中的每一個數字標號,標記他應該出現在哪一個位置。
然後從頭往後找,如果當前位置的數字不是應該在這個位置的數字。
那麼就找到應該在這個位置的數位位置,然後翻轉。如果還不是按順序排的話,就輸出no,否則輸出yes。
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<map>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define mem(a,b) (memset(a),b,sizeof(a))#define lmin 1#define rmax n#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1#define root lmin,rmax,1#define now l,r,rt#define int_now int l,int r,int rt#define INF 99999999#define LL __int64#define mod 1000000009#define eps 1e-6#define zero(x) (fabs(x)<eps?0:x)#define maxn 110000struct list{ int x; int id; int y;}node[maxn];int cmp1(list a,list b){ return a.x<b.x;}int cmp2(list a,list b){ return a.id<b.id;}int main(){ int n,m; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d",&node[i].x); node[i].id=i; } sort(node+1,node+n+1,cmp1); for(int i=1;i<=n;i++)node[i].y=i; sort(node+1,node+n+1,cmp2); int st,ed,i; st=ed=-1; for(i=1;i<=n;i++) { if(node[i].y!=i) { if(st==-1) { int j,k; for(j=i+1;j<=n;j++) { if(node[j].y==i)break; } for(k=j;k>=i;k--) { if(node[k].y!=i+(j-k))break; } if(k>=i)break; st=i; ed=j; i=j+1; } else break; } } if(i<=n)cout<<"no"<<endl; else { cout<<"yes"<<endl; if(st!=-1)cout<<st<<" "<<ed<<endl; else cout<<"1 1"<<endl; } } return 0;}
C:Predict Outcome of the Game
枚舉兩個差值的加號或減號。
對於每一種情況:
可以算出A,B,C最少贏幾個球。然後看看當前的贏球數是不是符合K。
然後看一下差值是否可以用(n-k)消除掉。
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<map>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define mem(a,b) (memset(a),b,sizeof(a))#define lmin 1#define rmax n#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1#define root lmin,rmax,1#define now l,r,rt#define int_now int l,int r,int rt#define INF 99999999#define LL __int64#define mod 1000000009#define eps 1e-6#define zero(x) (fabs(x)<eps?0:x)#define maxn 110000struct list{ int x; int id; int y;}node[maxn];int cmp1(list a,list b){ return a.x<b.x;}int cmp2(list a,list b){ return a.id<b.id;}int pan(LL n,LL k,LL d1,LL d2){ LL a,b,c; a=0; b=a+d1; c=b+d2; LL d; d=min(a,min(b,c)); if(d<0) { d=-d; a+=d; b+=d; c+=d; } d=max(a,max(b,c)); LL cha=0; cha=a+b+c; cha=k-cha; if(cha<0)return 0; if(cha%3)return 0; cha=0; cha+=d-a; cha+=d-b; cha+=d-c; LL cun=n-k; cun=cun-cha; if(cun<0)return 0; if(cun%3==0) { // cout<<n<<" "<<k<<" "<<d1<<" "<<d2<<endl; return 1; } else return 0;}void dos(){ LL n,k,d1,d2; cin>>n>>k>>d1>>d2; LL a,b,c; a=0; if(pan(n,k,d1,d2)) { cout<<"yes"<<endl; return; } if(pan(n,k,-d1,d2)) { cout<<"yes"<<endl; return; } if(pan(n,k,d1,-d2)) { cout<<"yes"<<endl; return; } if(pan(n,k,-d1,-d2)) { cout<<"yes"<<endl; return; } cout<<"no"<<endl;}int main(){ int t; LL n,k,d1,d2; while(~scanf("%d",&t)) { while(t--) { dos(); } } return 0;}
D:Count Good Substrings
假如字串為:abbabbbaaa
我們把這個字串如下記錄:
字串: a b a b a
數組num :1 2 1 3 3
數組的每一項代表這個字串這個位置的字元是由幾個字元壓縮成的。
對於迴文串的兩邊都是a的情況:
預先處理從起點走奇數步可到達多少a,走偶數步,可到達多少a。
然後從第一個a往後走,可在O(1)的複雜度內得出當前a的為迴文串的左邊,一共有幾個奇數子串,幾個偶數子串。
對於迴文串的兩邊都是b的情況,類似與兩邊都是a的情況。
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<map>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define mem(a,b) (memset(a),b,sizeof(a))#define lmin 1#define rmax n#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1#define root lmin,rmax,1#define now l,r,rt#define int_now int l,int r,int rt#define INF 99999999#define LL __int64#define mod 1000000009#define eps 1e-6#define zero(x) (fabs(x)<eps?0:x)#define maxn 110000LL a[maxn];char str[maxn];vector<char>vec;int num[maxn];LL s1,s2;LL cal(int x,int y){ if(x<0)return 0; LL a1,an,n; if(y==1) { if(x<2)return 0; an=x-1; if(x%2)a1=2; else a1=1; n=(an-a1)/2+1; return n*(a1+an)/(LL)2; } else { an=x; if(x%2)a1=1; else a1=2; n=(an-a1)/2+1; return n*(a1+an)/(LL)2; }}void dos(int x){ int n=vec.size(); LL even,odd; even=odd=0; LL sum=0; for(int i=1; i<=n; i++) { if(i%2==x) { LL a,b; a=num[i]/2; b=num[i]-a; if(sum%2)swap(a,b); even+=a;//偶 odd+=b;//奇 } sum+=num[i]; } sum=0; for(int i=x;i<=n;i+=2) { LL a,b; a=num[i]/2; b=num[i]-a; if(sum%2)swap(even,odd); sum=0; even-=a; odd-=b; sum+=num[i]; if(sum%2)swap(even,odd); sum=0; s1+=b*odd; s1+=a*even; s2+=b*even; s2+=a*odd; s1+=cal(num[i],1); s2+=cal(num[i],2); sum+=num[i+1]; }}int main(){ int n; LL s; while(~scanf("%s",str)) { vec.clear(); int len=strlen(str); int s=1; for(int i=1; i<len; i++) { if(str[i]!=str[i-1]) { vec.push_back(str[i-1]); num[vec.size()]=s; s=1; } else s++; } vec.push_back(str[len-1]); num[vec.size()]=s; s1=s2=0; dos(1); dos(0); cout<<s1<<" "<<s2<<endl; } return 0;}
E:Devu and Flowers
做這個題目出了一些莫名其妙的問題。。
做法:
如果每一個每一種花都有無限個,很明顯,有C(s+n-1,n-1)種取法。
如果某種花取x個以上,那麼就有C(s+n-1-x-1,n-1)種取法。
所以就用到容斥:
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<map>using namespace std;#define maxn 21#define LL __int64#define mod 1000000007LL num[21];LL inv[21];void gcd(LL a, LL b, LL& d, LL& x, LL& y) { if(!b){ d = a; x = 1; y = 0; } else{ gcd(b, a%b, d, y, x); y -= x*(a/b); }}LL getInv(LL a, LL n) { LL d, x, y; gcd(a, n, d, x, y); return d == 1 ? ( x + n ) % n : -1;}LL com(LL n,LL m){ if(n<m)return 0; LL ans; ans=1; for(LL i=n;i>=(n-m+1);i--) { ans=ans*(i%mod)%mod; ans=ans*inv[n-i+1]%mod; } return ans;}int main(){ LL n,s; for(int i=1;i<=20;i++)inv[i]=getInv(i,mod); while(~scanf("%I64d%I64d",&n,&s)) { LL r=0; int m=n; for(int i=0;i<m;i++) { scanf("%I64d",&num[i]); } LL ans=com(s+n-1,n-1); for(int i=1;i<(1<<m);i++) { int x=0; r=0; for(int j=0;j<m;j++) { if(i&(1<<j)) { x++; r+=num[j]+1; } } if(x&1) { ans-=com(s-r+n-1,n-1); ans=(ans%mod+mod)%mod; } else { ans+=com(s-r+n-1,n-1); ans=(ans%mod+mod)%mod; } } cout<<ans<<endl; } return 0;}