【提高组】

*我真的是搞不懂博弈论要怎么想*

 

P1199 三国游戏 (智商)

人的选择是每一行第二大中最大的组合,因为每行第一大一定会被计算机选。

保证计算机的选择结果小于人的结果,∵人可以把计算机最大的组合中的另一个数抢掉,而计算机不可能自动选到最大,否则人选择的就不是最大了(理解一下)

故人必胜,且最大的组合结果是每行第二大中的最大。

博弈论可以存在每次都必胜的结果别被题面&输出要求骗了。

#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
const int M=505;
int n,a[M][M];
int main(){
    scanf("%d",&n);
    For(i,1,n-1){
        For(j,i+1,n){
            scanf("%d",&a[i][j]);
            a[j][i]=a[i][j];
        }
    }
    int ans=0;
    For(i,1,n){
        sort(a[i]+1,a[i]+n+1);
        ans=ans>a[i][n-1]?ans:a[i][n-1];
    }
    printf("1\n%d\n",ans);
    return 0;
}
View Code

 

P1288 取数游戏II (智商)

*恕我直言Linux真的搞人*

经分析,先手决定游戏方向,先手开局位于a[n]与a[1]间,两种情况下必胜:

1. a[1]边即顺时针方向的第一条边不为0,从第一条边顺时针走碰到为0的边所经边数为偶

2. a[1]边即逆时针方向的第一条边不为0,从(逆时针走)第一条边顺时针走碰到为0的边所经边数为偶

若不是这两种情况中任何一种则必败。

#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define Dfor(i,r,l) for(int i=r;i>=l;i--)
using namespace std;
const int M=25;
int n,a[M];
inline int read(){
    int f=1,sum=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
    return f*sum;
}
int main(){
    n=read();
    For(i,1,n) a[i]=read();
    if(a[1]){
        For(i,1,n){
            if(!a[i]){
                if(!(i&1)){printf("YES\n");return 0;}
                break;
            }
        }
    }
    if(a[n]){
        Dfor(i,n,1){
            if(!a[i]){
                if(!((n-i+1)&1)){printf("YES\n");return 0;}
                break;
            }
        }
    }
    printf("NO\n");
    return 0;
}
View Code

 

P1290 欧几里德的游戏(智商)

假设y>x,有以下几种情况:

1. y==x或y为x倍数 先手胜

2. y=kx+b

    (1) k>2,则(x,kx+b)一定能转移为(x,x+b)-> (x,b),故当前操作者胜

    (2) k<2,则可转移为(y-x,x),递归求胜者

#include<bits/stdc++.h>
using namespace std;
int c,x,y;
bool f(int x,int y,int p){
    if(x==y||y>=2*x||!(y%x)) return p;
    else return f(y-x,x,p^1);
}
int main(){
    cin>>c;
    while(c--){
        cin>>x>>y;
        if(x>y) swap(x,y);
        if(!f(x,y,0)) cout<<"Stan wins"<<endl;
        else cout<<"Ollie wins"<<endl;
    }
    return 0;
}
View Code

 

P1247 取火柴游戏(智商)

https://www.luogu.org/blog/user53167/solution-p1247

#include<bits/stdc++.h> 
int n,a[500005],check;
using namespace std;
int main(){
    scanf("%d",&n);
    for(int i=1; i<=n; i++) scanf("%d",&a[i]),check^=a[i];
    if(!check){printf("lose\n");return 0;}
    for(int i=1; i<=n; i++){
        if((check^a[i])<a[i]){
            printf("%d %d\n",a[i]-(check^a[i]),i);
            for(int j=1; j<=n; j++){
                if(j!=i) printf("%d ",a[j]);
                else printf("%d ",check^a[i]);
            }
            break;
        }
    }
    return 0;
}
View Code
posted @ 2019-10-08 16:34  jian_song  阅读(123)  评论(0编辑  收藏  举报