传送门(参考博客):https://www.cnblogs.com/ECJTUACM-873284962/p/6921829.html
一、必胜点和必败点
必胜点(N)、必败点(P)这里我也非常不理解为什么和英文反着。
然后我觉得如果单纯解释必胜点和必败点是没有什么意思的,所以我们通过具体的题目看一下:
hdu 1847 Good Luck in CET-4 Everybody
作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的:
1、 总共n张牌;
2、 双方轮流抓牌;
3、 每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
4、 抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;
假设Kiki和Cici都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是Kiki先抓牌,请问谁能赢呢?
当然,打牌无论谁赢都问题不大,重要的是马上到来的CET-4能有好的状态。
这里就提供了几个关键信息:
①双方轮流抓牌②每人每次抓牌的个数是能是2的幂次(1,2,4,8,16)
③规定最后抓完牌的人获胜④规定Kiki先手。
然后这种题怎么做呢(套路一波)
其实就是找规律(和打表什么的差不多),
n = 0 必败点,因为无法进行操作
n = 1 必胜点,Kiki直接取2的0次幂就可以了,后面的人就没得取了。
以此类推,我们可以得到以下规律:
n : 0 1 2 3 4 5 6 ...
position: P N N P N N P ...
这样就可以得到规律,如果这个数%3余0,那么就是必败点;否则,它就是必胜点。
这里提供这道题目的代码:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
if(n%3)
{
printf("Kiki\n");
}
else
{
printf("Cici\n");
}
}
return 0;
}
进阶题目: hdu 2147 kiki's game
这里大家在讨论的时候用了一个很巧妙地办法:
就是根据题意,左下角的那个状态肯定是不能再继续进行下一步操作的状态,那么这个状态就是必败态。
后面完全可以画一个矩阵来进行理解:
这样的话就找出规律:如果说行数和列数都是奇数的话,那么这个时候就是必败态;否则就是必胜态
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m&&n&&m){
if(n%2!=0&&m%2!=0){
printf("What a pity!\n");
}else{
printf("Wonderful!\n");
}
}
return 0;
}
明天继续更~~