阿甘的珠宝 大数据博弈综合应用 SG函数 + 最后取为输或赢

题目来源:http://acm.fzu.edu.cn/problem.php?pid=1534

 Problem 1534 阿甘的珠宝

Accept: 95    Submit: 293
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

阿甘向来好运连连,他在好心人的带领下发现了基督山伯爵的宝藏。珠宝~~满眼都是珠宝!!!但是守护的神灵对阿甘提出了苛刻的要求,“你要珠宝,必须赢了我再说。”

阿甘要和守护神灵玩这样一个游戏,规则如下:

  1. 阿甘眼前有n堆珠宝,n≤10000;
  2. 每堆珠宝有mi个,0≤mi≤2^31-1;
  3. 每人每轮可以拿走一堆珠宝中2^i个,比如1,2,4,8…..(不能不拿);
  4. 阿甘先拿。
  5. 由守护申领决定取到最后一个赢or输。

守护神拥有千年的生命,无比智慧,阿甘是否能赢呢?

 Input

多组数据输入。每组数据包括:

一个整数n,接下来n行每行一个整数,表示mi。

第n+1行有一个数0或者1,表示取到最后一个赢或者输。

 Output

阿甘能赢则输出一行yes,否则输出no。

 Sample Input

2 5 4 0

 Sample Output

yes
 
分析:

1:每堆珠宝有mi个,0≤mi≤2^31-1;, 我们知道  这个大数据是没办法用数组存的,否则会超内存。 我们需要计算sg[mi] , 由于f[]是很规律的 步长,  我们 试着用文件的操作 找出这样的规律。

2:文件操作:

FILE fp;

fp = fopen("test.txt","w");

fclose(fp);

3:我们找出  sg[x]  =  x%3; 对的, 就是如此简单。

4:分两种情况:

当最后取完石子的 人 为赢。  则 异或值为0, 表示P_position. (先手必输态)

当最后取完石子的人  为输。 则 T2 和 S0 ,表示 P_position(先手必输态)

T2 表示 异或值=0 && 充裕堆>=2  充裕堆 表示 堆中的 石子 不止一个(注意 堆中的石子可以为0,因此还wa)
S0 表示 异或值!=0 && 充裕堆==0  
代码如下:
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#define Inf 0x7fffffff // 0x 是数字0,而不是字母o
#define N 10001
using namespace std;
typedef long long LL;
int main(){
    int n,unalone,ans,flag,temp,zero;
    while(cin>>n)
    {
        unalone=0,ans=0,zero=0;
        for(int i=0;i<n;i++)
         {
             cin>>temp;
             if(temp>1) unalone++;
             if(temp==0) zero++;
             ans^=(temp%3);
         }
        cin>>flag;
        if(flag ==0)
        {
            if(ans) puts("yes");
            else puts("no");
        }
        else
        {
            if(zero == n) {puts("yes");continue;}
            if((ans==0 && unalone>=2) || (ans && unalone==0))
                puts("no");
            else puts("yes");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zn505119020/p/3614130.html