zoukankan      html  css  js  c++  java
  • 【BZOJ2927】[POI1999] 多边形之战(博弈论SB题)

    点此看题面

    大致题意:(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为奇数,先手赢
    }
    
  • 相关阅读:
    【Git】rebase 用法小结(转)
    修饰符访问权限。
    throws与throw关键字。
    多线程,同步代码块。
    多线程,设置线程的优先级。
    多线程,加入线程。
    多线程,守护线程。
    多线程,休眠线程。
    多线程,获取当前线程的对象。
    多线程获取名字和设置名字。
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2927.html
Copyright © 2011-2022 走看看