码迷,mamicode.com
首页 > 其他好文 > 详细

[原博客] POJ 1740 A New Stone Game

时间:2014-09-08 00:57:16      阅读:311      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   strong   for   

题目链接
题意:有n堆石子,两人轮流操作,每次每个人可以从一堆中拿走若干个扔掉(必须),并且可以从中拿走一些分到别的有石子的堆里(可选),当一个人不能拿时这个人输。给定状态,问是否先手必胜。

我们参考普通取石子游戏可知,如果只有一堆,先手必胜。
如果有两堆一样,先手必败,对称博弈,第一个人怎么取,第二个人也可以怎么取,直到第一个人无法取为止。
如果有四堆两两一样,还是先手必败,第一个人无论如何取,第二个人可以再次取成两两一样。
如果有2*k堆两两一样,还是先手必败。
注意:除了上述情况,都是先手必胜
因为先手无论奇偶总能把最多的那堆匀到其他堆上使之两两相等,(若堆数是奇数那么最多的那堆就不剩了,若堆数是偶数,那么最多的那堆应该剩下和最小的一堆进行匹配)。
证明如下图。设一共有9堆分别是1,2,3,3,5,7,8,9,11(排序后)。

bubuko.com,布布扣

最大堆为11,蓝色的为原来高度,绿色的为要补的,可以看出绿色的和总小于最大值(黄色)。

bubuko.com,布布扣
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
 
//by zrt
//problem:
using namespace std;
typedef long long LL;
const int inf(0x3f3f3f3f);
const double eps(1e-9);
bool f[105];
int n;
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    while(scanf("%d",&n),n){
        int ans=0;
        memset(f,0,sizeof f);
        for(int i=0,x;i<n;i++){
            scanf("%d",&x);
            if(f[x]) ans++;
            else ans--;
            f[x]=!f[x];
        }
        if(ans) puts("1");
        else puts("0");
    }
    
    return 0;
}
View Code

 

[原博客] POJ 1740 A New Stone Game

标签:style   blog   http   color   os   io   ar   strong   for   

原文地址:http://www.cnblogs.com/zrts/p/3960983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!