Assignment 5: Combinatorial Games

来源:互联网 发布:月薪3万的程序员 编辑:程序博客网 时间:2024/05/16 12:59
  • 2234 Matches Game (1)

  • 2484 A Funny Game (2)

  • 3480 John (3)

  • 2505 A multiplication game (3)

  • 1678 I Love this Game! (3)

  • 1704 Georgia and Bob (5)

  • 2960 S-Nim (5)

  • 2232 New Stone-Forfex-Cloth Game (6)

  • 2348 Euclid's Game (6)

  • 1143 Number Game (7)

  • 3317 Stake Your Claim (7)

  • 1740 A New Stone Game (7)


    poj1678

    博弈求差值最大,在最优里取最优

    #include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespace std;#define maxn 10010int d[maxn],c[maxn],a[maxn],n,A,B;bool dd[maxn],cc[maxn];int gaod(int i,int now);int gaoc(int i){   // printf("gaoc i=%d\n",i);    if(i>=n) return 0;    if(cc[i]) return c[i];    int j;    cc[i]=1;    for(j=i+1;j<n;++j){        if(a[j]>=a[i]+A && a[j]<=a[i]+B){            break;        }    }    if(j>=n) return c[i]=a[i];   // printf("i=%d j=%d\n",i,j);    c[i]=a[j]-gaod(j+1,a[j]);    for(++j;j<n;++j){        if(a[j]>a[i]+B) break;        c[i]=max(c[i],a[j]-gaod(j+1,a[j]));    }   // printf("di=%d\n",c[i]);    return c[i]=a[i]-c[i];}int gaod(int i,int now){    if(i>=n) return 0;    if(dd[i]) return d[i];    int j;    dd[i]=1;    for(j=i;j<n;++j){        if(a[j]>=now+A && a[j]<=now+B){            break;        }    }    if(j>=n) return d[i]=0;   // printf("i=%d now=%d aj=%d\n",i,now,a[j]);    d[i]=gaoc(j);  //  printf("gaoc [j=%d]=%d\n",j,gaoc(j));    for(++j;j<n;++j){        if(a[j]>now+B) break;        d[i]=max(d[i],gaoc(j));    }    return d[i];}int main(){   // freopen("test.in","r",stdin);    int i,t,T,x;    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&t,&A,&B);        memset(dd,0,sizeof(dd));        memset(cc,0,sizeof(cc));        n=0;        for(i=0;i<t;++i){            scanf("%d",&x);            if(x<=0) continue;            a[n++]=x;        }        sort(a,a+n);        printf("%d\n",gaod(0,0));      //  printf("gaod2=%d\n",gaod(2,a[1]));    }    return 0;}

    poj1704

    阶梯博弈,两两一组,考虑偶数位置

    #include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;int a[1010],n;int main(){    int i,s;    scanf("%*d");    while(scanf("%d",&n)!=EOF){        if(n&1){            a[0]=0;            for(i=1;i<=n;++i) scanf("%d",&a[i]);            ++n;        }else{            for(i=0;i<n;++i) scanf("%d",&a[i]);        }        sort(a,a+n);        s=0;        for(i=0;i<n;i+=2){            s^=(a[i+1]-a[i]-1);        }        printf("%s will win\n",s?"Georgia":"Bob");    }    return 0;}

    poj2348

    博弈中的黄金分割

    #include<cstdio>void swap(int &a,int &b){    int t=a;    a=b;    b=t;}void print(int f){    printf("%s wins\n",f?"Ollie":"Stan");}int main(){    int a,b,f;    while(scanf("%d%d",&a,&b)!=EOF && a){        f=0;        if(a>b) swap(a,b);        while(1){            if(b/a>=2 || b%a==0){                print(f);                break;            }            b-=a;            swap(a,b);            f=1-f;        }    }    return 0;}

    poj3317

    博弈求max-min,用alpha-beta剪枝

    #include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<iostream>using namespace std;#define inf 0x7fffffffchar map[10][10];int n,cnt,pow3[13],d[60000],x[13],y[13],px,py,ans;int gaomax(int state,int dep,int now,int alpha);int gaomin(int state,int dep,int now,int beta);int vis[10][10],dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};typedef pair<int,int> pii;queue<pii> q;int find(char c){    int i,j,temp,k,xx,yy,tx,ty,a;    a=0;    memset(vis,0,sizeof(vis));    while(!q.empty()) q.pop();    for(i=0;i<n;++i){        for(j=0;j<n;++j){            if(!vis[i][j] && map[i][j]==c){                temp=1;                vis[i][j]=1;                q.push(make_pair(i,j));                while(!q.empty()){                    tx=q.front().first,ty=q.front().second;                    q.pop();                    for(k=0;k<4;++k){                        xx=tx+dx[k],yy=ty+dy[k];                        if(xx>=0 && xx<n && yy>=0 && yy<n && !vis[xx][yy] && map[xx][yy]==c){                            vis[xx][yy]=1;                            q.push(make_pair(xx,yy));                            ++temp;                        }                    }                }                a=max(temp,a);            }        }    }    return a;}int gao(){    return find('0')-find('1');}int gaomax(int state,int dep,int now,int alpha){   // printf("max state=%d\n",state);    if(d[now]!=-inf) return d[now];    if(!state) return d[now]=gao();    int i,j,temp,a=-inf;    for(i=0;i<cnt;++i){        if(state&(1<<i)){            map[x[i]][y[i]]='0';            temp=gaomin(state^(1<<i),dep+1,now+pow3[i],a);          //  printf("temp=%d\n",temp);            map[x[i]][y[i]]='.';            if(temp>=alpha) return temp;            a=max(a,temp);            if(!dep && a>ans){                ans=a;                px=x[i],py=y[i];            }        }    }    return d[now]=a;}int gaomin(int state,int dep,int now,int beta){   // printf("min state=%d\n",state);    if(d[now]!=-inf) return d[now];    if(!state) return d[now]=gao();    int i,j,temp,a=inf;    for(i=0;i<cnt;++i){        if(state&(1<<i)){            map[x[i]][y[i]]='1';            temp=gaomax(state^(1<<i),dep+1,now+2*pow3[i],a);            map[x[i]][y[i]]='.';            if(temp<=beta) return temp;            a=min(a,temp);        }    }    return d[now]=a;}int main(){   // freopen("test.in","r",stdin);    int i,j,c0,c1;    pow3[0]=1;    for(i=1;i<=10;++i) pow3[i]=pow3[i-1]*3;    while(scanf("%d",&n)!=EOF && n){        c0=c1=cnt=0;        for(i=0;i<n;++i){            scanf("%s",map[i]);            for(j=0;j<n;++j){                if(map[i][j]=='.'){                    x[cnt]=i,y[cnt]=j;                    ++cnt;                }else if(map[i][j]=='0'){                    ++c0;                }else{                    ++c1;                }            }        }        if(c0>c1){            for(i=0;i<n;++i){                for(j=0;j<n;++j){                    if(map[i][j]=='0'){                        map[i][j]='1';                    }else if(map[i][j]=='1'){                        map[i][j]='0';                    }                }            }        }        for(i=0;i<pow3[cnt];++i) d[i]=-inf;        ans=-inf;        gaomax((1<<cnt)-1,0,0,inf);        printf("(%d,%d) %d\n",px,py,ans);    }    return 0;}

    poj1740

    博弈原则,偶数堆且大小相邻两堆个数都相同为P态,否则为N态。

    #include<cstdio>#include<iostream>#include<algorithm>using namespace std;int a[1010];int main(){    int n,i,s,f;    while(scanf("%d",&n)!=EOF && n){        for(i=0;i<n;++i) scanf("%d",&a[i]);        sort(a,a+n);        for(s=0;s<n;++s){            if(a[s]) break;        }        if((n-s)%2==0){            f=1;            for(i=s;i<n;i+=2){                if(a[i]!=a[i+1]){                    f=0;                    break;                }            }        }else f=0;        printf("%d\n",1-f);    }    return 0;}



原创粉丝点击