POJ 1740[A New Stone Game] 题解

来源:互联网 发布:蓝光原盘播放软件 编辑:程序博客网 时间:2024/06/05 01:58

(传送门)

题目大意

现有一个游戏,两个操作者轮流操作,每次操作需要选择一根柱子,首先至少需要该柱子上的一颗石子,然后可以对其剩下的石子任意进行分配,可以留在原柱子上,也可以放在其他有石子的柱子上,但不可以放在没有石子的柱子上。无法操作的人输,问先手是否有必胜策略。

题目分析

一开始是往SG函数的方面上想的,不过没什么思路,然后找规律,但菜鸡fhj找不出来,最后上网查,发现这道题就是找规律,不过要进行一定的推论。

首先分析n=1的情况,那么先手必胜,很显然。
n=2,此时如果两堆相等则后手只用和先手一样决策即可保证胜利,后手必胜。若不同则先手可以使其变成相等的两堆,先手必胜。
n=3,此时先手可以把该状态转换成两堆相等的石子状态,而且可以一步完成,所以依旧先手必胜。
n=4,此时两个人都不想自己取完后只有三个堆然后让对手华丽丽的胜利,所以就是能拖就拖,但如果到了4个堆都是1个的时候,还怎么拖呢,所以就是如何不会到了自己这就4个堆都只有一个石子?
联系前面的内容,然后就各种复杂的分析……发现,如果4个堆两两相等,那么先手必败,否则先手必胜。
……

所以规律:
1.当n为奇数的时候,先手必胜。
2.当n为偶数的时候,如石子堆两两相等,则先手必败,反之先手必胜。

这道题告诉我们,博弈论的题目最重要的解题方法就是:找规律!

#include<cstdio>#include<algorithm>using namespace std;int n,a[15];inline void readi(int &x){    x=0; char ch=getchar();    while ('0'>ch||ch>'9') ch=getchar();    while ('0'<=ch&&ch<='9')    {        x=x*10+ch-'0';        ch=getchar();    }}int main(){    freopen("stone.in","r",stdin);    freopen("stone.out","w",stdout);    readi(n);    while (n)    {        for (int i=1;i<=n;i++) readi(a[i]);        if (n%2) printf("1\n");        else        {            sort(a+1,a+n+1); bool pd=true;            for (int i=1;i<n;i++)              if (i%2&&a[i]!=a[i+1]) {pd=false; printf("1\n"); break;}            if (pd) printf("0\n");        }        readi(n);    }    return 0;}

Orz zzkksunboy
Orz zzkksunboy
Orz zzkksunboy
重要的事情……你懂得

原创粉丝点击