[hdu1847]博弈,推理

题意:一堆石子,有n个,两个人轮流取,每次都只能取2的幂次方个数,不能取的人输

思路:首先0是必败态,2的所有幂次都是必胜态。由于选的数模3只能是1或2,恰好又都是2的幂次,0,、3都为必败态,猜想3的所有倍数也为必败态,证明如下:设状态为x=3k,先手任选一个t,那么(x-t)%3不是1就是2,后手就取(x-t)%3,使得先手面临的状态始终是3的倍数,并且只要先手可以取,那么后手也就可以取,所以3的倍数都是必败态。对于x=3k+p,p=1或2的状态,先手都可以将其变成必败态,即先手取p=x%3即可,因此为必胜态。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/* ******************************************************************************** */

#include <iostream>                                                                 //

#include <cstdio>                                                                   //

#include <cmath>                                                                    //

#include <cstdlib>                                                                  //

#include <cstring>                                                                  //

#include <vector>                                                                   //

#include <ctime>                                                                    //

#include <deque>                                                                    //

#include <queue>                                                                    //

#include <algorithm>                                                                //

#include <map>                                                                      //

#include <cmath>                                                                    //

using namespace std;                                                                //

                                                                                    //

#define pb push_back                                                                //

#define mp make_pair                                                                //

#define X first                                                                     //

#define Y second                                                                    //

#define all(a) (a).begin(), (a).end()                                               //

#define fillchar(a, x) memset(a, x, sizeof(a))                                      //

                                                                                    //

typedef pair<intint> pii;                                                         //

typedef long long ll;                                                               //

typedef unsigned long long ull;                                                     //

                                                                                    //

#ifndef ONLINE_JUDGE                                                                //

void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}    //

void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>                    //

void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;          //

while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>      //

void print(const T t){cout<<t<<endl;}template<typename F,typename...R>              //

void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>   //

void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}   //

#endif // ONLINE_JUDGE                                                              //

template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}        //

template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}        //

template<typename T>                                                                //

void V2A(T a[],const vector<T>&b){for(int i=0;i<b.size();i++)a[i]=b[i];}            //

template<typename T>                                                                //

void A2V(vector<T>&a,const T b[]){for(int i=0;i<a.size();i++)a[i]=b[i];}            //

                                                                                    //

const double PI = acos(-1.0);                                                       //

const int INF = 1e9 + 7;                                                            //

                                                                                    //

/* -------------------------------------------------------------------------------- */

int main() {

#ifndef ONLINE_JUDGE

    freopen("in.txt""r", stdin);

    //freopen("out.txt", "w", stdout);

#endif // ONLINE_JUDGE

    int n;

    while (cin >> n) {

        puts(n % 3? "Kiki" "Cici");

    }

    return 0;

}

/* ******************************************************************************** */

时间: 2024-08-28 09:03:34

[hdu1847]博弈,推理的相关文章

hdu1847 博弈

找规律. #include<stdio.h> #include<math.h> #include<string.h> int main() { int i,n; while(scanf("%d",&n)!=EOF) { i=n%3; if(i==1||i==2) printf("Kiki\n"); else printf("Cici\n"); } }

(zst的博弈) 【推理+找规律】

题目: 甲乙两人玩一个游戏: 一张卡片上有个数字,甲乙两人轮流操作, 若当前卡片上的数字为x, 每次操作可以把它变为x+1或2x, 且不能超过n (例如n=8,x=6,只能变为7而不能变为12), 每次甲首先在卡片上写1,规定写n的人获胜.给定n, 问甲是否有必胜策略? 分析: 看起来像一道博弈论的题,但实际上仅需细心的推理,耐心的找规律即可. 1.因为甲先写的1,所以乙的所有奇数全部要从甲的偶数哪里加1得来,因此如果n为奇数,甲只要保证自己写的数全是      奇数即可,因此奇数的情况下,甲赢

HDU1847 Good Luck in CET-4 Everybody!【博弈】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1847 题目大意: 有N张牌,两个人轮流抓,每次抓的牌数只能是2的幂次(2^0.2^1.2^2.-).最后抓完牌的人获胜. Kiki和Cici都是足够聪明的学生,Kiki先抓,输出赢得比赛的人. 思路: 找必败点,很容易知道当N==3时是一个必败点,因为只能取1或是2,而剩下的牌肯定能被对手取完, 所以3是一个必败点.4能取1把场面变为3,所以4是必胜点,5能取2把场面变为3.而6的话,要么取 完剩

hdu1847 Good Luck in CET-4 Everybody!(巴什博弈)

http://acm.hdu.edu.cn/showproblem.php?pid=1847 从1开始枚举情况,找规律.1先手胜2先手胜3先手败4先手胜5先手胜... n只要能转移到先手败,就可以实现先手胜,否则n情况下就是先手败.发现规律时%3 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib>

博弈简单题目

HDU 1846 有n个石头,2个人,每次只能拿m个,谁最后拿完谁赢. 假如n%(m+1)==0,第一个人拿x个,那么第二个人拿m+1-x个,第一个人拿完之后,第二个人始终能拿. HDU 2147 有n*m个格子和一个棋子,棋子初始在(1,m),每次移动棋子只能到3个位置(左边,下边和左下),谁不能走谁就输. HDU 2188 和HDU1846一样 HDU 2149 和HDU1846类似 HDU 1847 有n张牌,可以拿2的幂次(即:1,2,4,8,16-)张拍,谁先拿完谁赢. 打SG函数表,

最强头脑决定战中的尼姆博弈

最近看了一个日本综艺——最强头脑王决定战,顿觉以前看过的国内烧脑节目,类似“一站到底”之流与之相比真是相形见绌.“一站”说到底只是比谁题库背得熟,而日本这个真的是记忆.计算.观察.推理等各种能力的综合考察,比赛选手们各显神通,观众如我看得也是如痴如醉. 其中比赛到第二轮时有一道题如下:有四堆不同色的棋子,每堆分别有3.5.6.7枚,由选手和电脑开始依次从其中取出一些棋子,每次只可取同一堆的任意枚,如此交替直至取完所有棋子,谁取到最后一枚棋子谁输. 当时水上小哥不假思索地取子很轻松就赢了,让评委们

阶梯博弈(没怎么搞懂)

首先是对阶梯博弈的阐述...博弈在一列阶梯上进行...每个阶梯上放着自然数个点..两个人进行阶梯博弈...每一步则是将一个集体上的若干个点( >=1 )移到前面去..最后没有点可以移动的人输.. 如这就是一个阶梯博弈的初始状态 2 1 3 2 4 ... 只能把后面的点往前面放...如何来分析这个问题呢...其实阶梯博弈经过转换可以变为Nim..把所有奇数阶梯看成N堆石子..做nim..把石子从奇数堆移动到偶数堆可以理解为拿走石子..就相当于几个奇数堆的石子在做Nim..( 如所给样例..2^3

hdoj 2516 取石子游戏(斐波那契博弈)

Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win".先取者胜输出"First win". Input 输入有多组.每组第1行是2<=n<2^31. n=0退出. Output 先取者负输出"Second win". 先取者胜输出"First win". 参看Samp

[博弈]

http://blog.sina.com.cn/s/blog_83d1d5c70100y9yd.html ----很好的一篇sg函数资料,可惜不是sina用户转载不了. hdu1846(记忆化搜索) #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int cas,n,m; int sg[1010]; int dfs(int x) { if(x<=m)return