大致题意: 用(n-3)条对角线将一个(n)边形分为(n-2)个三角形,其中一个三角形是黑色的。每人每次可以剪开一条对角线,问谁有先剪下黑色三角形的必胜策略。
前言
明明很想认真学学博弈论的说,却不知道为什么会找到这样一道SB题。。。
这种题目只是又来水一发博客而已。。。
分类讨论
实际上,题目中给出(n-2)个三角形,除了黑色三角形外其余的都是没用的。
而对于这个黑色三角形,我们只需知道它有几条边不在边界上(即需要剪几次),然后这个三角形也没用了。
接下来,我们就对它需要剪几次来分类讨论:
- (1)次:显然先手必赢。
- (2)次:显然当谁剪了第一次,另一个人可以立刻剪掉第二次,然后就赢了。因此,每个人都会尽量避免去剪第一次。那么他们能干什么呢?只能去剪剩余的(n-5)条对角线,直至剪完为止。也就是说,如果(n-5)为奇数,先手赢,否则后手赢。
- (3)次:和上一种情况很像,谁剪了第二次,另一个人可以立刻剪掉第三次。而第一次剪不剪其实没什么大影响,因此同样是可以在(n-5)条对角线中任意剪,直至剪完。最终的结论也是一样的。
综上所述,先手赢的条件为三角形只需剪(1)次,或(n-5)为奇数(即(n)为偶数)。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 50000
using namespace std;
int n,a,b,c;
int main()
{
#define S(x,y) (abs((x)-(y))^1&&abs((x)-(y))^(n-1))//判断三角形这条边是否需要剪
scanf("%d%d%d%d",&n,&a,&b,&c);RI t=S(a,b)+S(a,c)+S(b,c);
return puts((t==1||(n-5)&1)?"TAK":"NIE"),0;//如果t=1,或n-5为奇数,先手赢
}