hdu 3032 sg打表找规律 *

有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) ,也可以选择将这堆石子分成任意的两堆。alice与bob轮流取,取走最后一个石子的人胜利。

打表代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 const int N=1000010;
 7 int sg[N];
 8 //注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
 9 //n是集合s的大小 S[i]是定义的特殊取法规则的数组
10 int s[110];
11 int SG_dfs(int x)
12 {
13     int i;
14     if(sg[x]!=-1)
15         return sg[x];
16     bool vis[110];
17     memset(vis,0,sizeof(vis));
18     for(int i=x-1;i>=0;i--)     //第一种取法
19         vis[SG_dfs(i)]=1;
20     for(i=1;i<=x/2;i++)     //分开取法
21     {
22         int ans=0;
23         ans^=SG_dfs(i);
24         ans^=SG_dfs(x-i);
25         vis[ans]=1;
26     }
27     int e;
28     for(i=0;;i++)
29         if(!vis[i])
30         {
31             e=i;
32             break;
33         }
34     return sg[x]=e;
35 }
36 int main()
37 {
38     int t,n;
39     scanf("%d",&t);
40     memset(sg,-1,sizeof(sg));
41     while(t--)
42     {
43         scanf("%d",&n);
44         int x;
45         for(int i=0;i<n;i++)
46         {
47             scanf("%d",&x);
48             SG_dfs(x);
49             printf("sg[%d]=%d\n",x,sg[x]);
50         }
51         for(int i=0;i<=100;i++){
52             printf("%d: %d\n",i,sg[i]);
53             //if(i%10==0)
54                 //system("pause");
55         }
56         printf("\n");
57     }
58     return 0;
59 }

之后异或一下即可,2333

时间: 2024-10-14 05:33:01

hdu 3032 sg打表找规律 *的相关文章

HDU 3032 (SG打表找规律)

题意: 有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) ,也可以选择将这堆石子分成任意的两堆.alice与bob轮流取,取走最后一个石子的人胜利. 思路: 因为数的范围比较大,所以最好通过SG打表的结果找出规律在解. sg(4k+1)=4k+1;sg(4k+2)=4k+2;sg(4k+3)=4k+4; sg(4k)=4k-1; 1 2 4 3 5 6 8 7 Sample Input232 2 323 3 Sample OutputAliceBob SG打表找规律

hdu 2147 kiki&#39;s game(DP(SG)打表找规律)

题意: n*m的棋盘,一枚硬币右上角,每人每次可将硬币移向三个方向之一(一格单位):左边,下边,左下边. 无法移动硬币的人负. 给出n和m,问,先手胜还是后手胜. 数据范围: n, m (0<n,m<=2000) 思路: dp[i][j]=0,说明从(i,j)这个点到时左下角先手败.dp[i][j]=1则先手胜. 然后记忆搜.但是记忆搜会超时. 搜完把整张表打出来,发现规律了,,,,然后,,,代码剩几行了. 代码: ///打表观察 /* int f[2005][2005]; int go(in

HDU 4203 博弈 打表找规律

http://acm.hdu.edu.cn/showproblem.php?pid=4203 一堆数量为s的硬币,两个人轮流从中取硬币,最后取完的人获胜,其中每次只能取k的n次方个硬币(n = 0, 1, 2, 3-),求想要取胜,当前要取走的最少硬币数. s的范围是1e9,直接储存sg函数是不现实的,所以考虑打表找找规律看. 通过打表可以得出规律: 当k为偶数时,sg函数值依次为 0 1 0 1 0 1 0 1- 当k为奇数时,sg函数值依次为 0 1 0 1 0 1-k(总长度为k + 1)

石油大训练 Little Sub and Johann (博弈SG打表找规律)

Little Sub and Johann 题目描述 Little Sub and Johann are good friends and they often play games together. Recently, they like playing with stones.They have n piles of stones initially and they should make one of following movements by turns:1.Erase a pil

HDU 3032 Nim or not Nim?(博弈 SG打表找规律)

传送门 Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1457    Accepted Submission(s): 720 Problem Description Nim is a two-player mathematic game of strategy in which players take

HDU 4588 Count The Carries 数位DP || 打表找规律

2013年南京邀请赛的铜牌题...做的很是伤心,另外有两个不太好想到的地方....a 可以等于零,另外a到b的累加和比较大,大约在2^70左右. 首先说一下解题思路. 首先统计出每一位的1的个数,然后统一进位. 设最低位为1,次低位为2,依次类推,ans[]表示这一位上有多少个1,那么有 sum += ans[i]/2,ans[i+1] += ans[i]/2; sum即为答案. 好了,现在问题转化成怎么求ans[]了. 打表查规律比较神奇,上图不说话. 打表的代码 #include <algo

HDU 4919 打表找规律 java大数 map 递归

== oeis: 点击打开链接 瞎了,x.mod(BigInteger.ValueOf(2)).equal( BigInteger.ValueOf(1)) 写成了 x.mod(BigInteger.ValueOf(2)).equal( 1 ) T^T100块没了... import java.math.*; import java.util.*; import static java.lang.System.out; import java.io.*; public class Main { s

Nim or not Nim? hdu3032 SG值打表找规律

Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 858    Accepted Submission(s): 412 Problem Description Nim is a two-player mathematic game of strategy in which players take turns

hdu_5795_A Simple Nim(打表找规律的博弈)

题目链接:hdu_5795_A Simple Nim 题意: 有N堆石子,你可以取每堆的1-m个,也可以将这堆石子分成3堆,问你先手输还是赢 题解: 打表找规律可得: sg[0]=0 当x=8k+7时sg[x]=8k+8, 当x=8k+8时sg[x]=8k+7, 其余时候sg[x]=x:(k>=0) 1 #include<cstdio> 2 3 int main() 4 { 5 int t,n,ans,tp; 6 scanf("%d",&t); 7 while