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)

最后根据s和k得出的sg函数值即为答案。

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    int n, s, k;
    scanf("%d", &n);
    while (n--) {
        scanf("%d %d", &s, &k);
        if (k % 2) {
            if (s % 2) {
                printf("1\n");
                continue;
            }
            else {
                printf("0\n");
                continue;
            }
        }
        else {
            if ((s + 1) % (k + 1) == 0) {
                printf("%d\n", k);
                continue;
            }
            else if(((s + 1) % (k + 1)) % 2) {
                printf("0\n");
                continue;
            }
            else {
                printf("1\n");
                continue;
            }
        }
    }
    return 0;
}
时间: 2024-08-06 11:23:22

HDU 4203 博弈 打表找规律的相关文章

EOJ——2019.9月赛 A 才艺展示 (博弈+打表找规律)

题目链接:https://acm.ecnu.edu.cn/contest/196/problem/A/ 题目:  解题报告: 由于必胜点是 n,所以 n 点的必胜状态为yes(走到这个点的人必胜),考虑 n-1 到 n/2+1 这一段(因为这一段都无法整除),所以 i 点的状态可以由i+1得到,接着从再从n/2推到1,由于有两种取法,所以对于当前状态 i,如果 i+1或者 2*i 的状态(这两点的状态前面已经推出来了),有一个为yes,那么这个 i 点的状态就为no(因为前面是由两者取最优的决策

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];

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 2147 kiki&#39;s game(博弈图上找规律)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2147 题目大意:给你一个n*m的棋盘,初始位置为(1,m),两人轮流操作,每次只能向下,左,左下这三个方向移动,谁最后无法移动棋子就输掉比赛,问先手是否会获胜. 解题思路:简单题,P/N分析找规律,以(n,m)点为结束点推到起始点,如图: 发现每个田字格的状态都是一样的,因为(n,m)点一定时P态,所以可以得出规律:只有当(m%2==1&&n%2==1)时,先手才会输. 代码: 1 #incl

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

HDU2149-Good Luck in CET-4 Everybody!(博弈,打表找规律)

Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4762    Accepted Submission(s): 3058 Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?或许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和C

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_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