POJ-3537(Crosses and Crosses)——博弈论,SG函数
2015-09-24 19:41
459 查看
题意:两个人玩游戏,规则是在标有1,2,3,4,5...,n的格子上画X,一直画一直画,画到有三个X相邻就获胜。
思路:在试着画了几组之后,明白了要有获胜的情况必须现有类似_XX_和X_X的情况。所以在画X的时候就是要避免这种情况,也就是说在画完一个X之后,这个X的左边两格和右边两格就不可以再画X了(否则对手就赢了)。那么我画完一个X就是将这个游戏分为左半边游戏和右半边游戏,即可以设我画X的位置是第i个格子,那么左半边游戏就是一个新的有i-1-2个格子的游戏(若数字小于等于0,那么这里的SG值就是0),右半边就是一个新的有n-i-2个格子的游戏(如果是负数与前面括号中说得一样),那么就将他们异或起来,即可以算出当前游戏的SG值。然后进行NIM博弈判断,就可以简单的得出赢还是输。(我的i是从1开始取到n,答案和网上从3开始取到n-2的答案一样,其实我是不太懂为什么)
代码:
思路:在试着画了几组之后,明白了要有获胜的情况必须现有类似_XX_和X_X的情况。所以在画X的时候就是要避免这种情况,也就是说在画完一个X之后,这个X的左边两格和右边两格就不可以再画X了(否则对手就赢了)。那么我画完一个X就是将这个游戏分为左半边游戏和右半边游戏,即可以设我画X的位置是第i个格子,那么左半边游戏就是一个新的有i-1-2个格子的游戏(若数字小于等于0,那么这里的SG值就是0),右半边就是一个新的有n-i-2个格子的游戏(如果是负数与前面括号中说得一样),那么就将他们异或起来,即可以算出当前游戏的SG值。然后进行NIM博弈判断,就可以简单的得出赢还是输。(我的i是从1开始取到n,答案和网上从3开始取到n-2的答案一样,其实我是不太懂为什么)
代码:
#include <map> #include <set> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; #define maxn 2000+5 #define PB push_back #define clr(x,y) memset(x,y,sizeof(x)) int a[maxn]; int SG(int n) { if(n<0)return 0; if(a >=0)return a ; bool vis[1000]; clr(vis,0); for(int i=1;i<=n;i++) { int ans=SG(i-1-2)^SG(n-i-2); vis[ans]=1; } int k=-1; for(int i=0;k==-1;i++) if(!vis[i]) k=i; return a =k; } int main() { int n; clr(a,-1); a[0]=0; while(~scanf("%d",&n)) { SG(n); if(a !=0)printf("1\n"); else printf("2\n"); } return 0; }
相关文章推荐
- 使用Lambda与不使用Lambda表达式
- Codeforces 338D GCD Table 中国剩余定理
- 星型模型和雪花型模型比较
- 实用SQL语句大全
- jquery的clone办法bug修复
- PAT(甲级)1024
- 沙盒机制、NSBundle、简单对象写入文件
- POJ 2828 Buy Tickets
- 正在腾飞的教育界,你了解多少?
- 2016 百度研发岗面试总结
- PAT(甲级)1023
- mysql中You can't specify target table for update in FROM clause错误 转
- PAT(甲级)1022
- Struts2的action配置方法
- Cocos2d-x中的CC_CALLBACK_0,1,2,3
- 第二次作业(个人项目实践)
- 1 kvo(键值监听)
- Maven的配置文件pom.xml
- iOS_XML与JSON解析
- Android中自定义弹窗提醒控件