zoukankan      html  css  js  c++  java
  • CF154D. Flatland Fencing [博弈论 对称 平局]

    传送门

    题意:


    背景是$knights' tournament$,好棒的样子!

    这道题不一样很恶心的地方就是有平局的存在

    首先判断能不能一步杀

    不能的话,如果可以走$0$步或者$a,b$一负一正那么一定会平局,因为这时候两人移动范围相同肯定不会去送死啊

    剩下的,可以简化成,有$d=|x_1-x_2|$个石子,每人每次可以取$[a,b]$个,谁取完最后一颗就胜利

    这时候$SG$定理显然没什么用,应该往“对称”方向考虑

    发现一个$a+b$一定可以两人走完

    然后按照$d%(a+b)$的结果分类

    注意如果处在$[1,a-1] igcup [b+1,a+b-1]$也是平局!

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=1005;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int x1,x2,a,b,f=1;
    void solve(){
        if(x1+a<=x2 && x2<=x1+b) {puts("FIRST"),printf("%d
    ",x2);return;}
    
        if(a==0 || b==0) {puts("DRAW");return;}
        if(a<0 && b>0) {puts("DRAW");return;}
        if(a>0){
            if(x1>x2) {puts("DRAW");return;}
        }else{
            if(x1<x2) {puts("DRAW");return;}
            a=-a;b=-b;swap(a,b);f=-1;
        }
        int d=abs(x1-x2),t=d%(a+b);//printf("d %d %d
    ",d,t);
    
        if(t==0) puts("SECOND");
        else if(a<=t&&t<=b) puts("FIRST"),printf("%d
    ",x1+t*f);
        else puts("DRAW");
    }
    int main(){
        //freopen("in","r",stdin);
        x1=read();x2=read();a=read();b=read();
        solve();
    }
  • 相关阅读:
    51nod 1621 花钱买车牌 优先队列
    最大字段和 51nod 1049 水水水水水水水水水水水水
    大数相乘 51nod 1027 水题
    逆序数 51nod 1019 归并 分治
    最长公共子序列 LCS 递归 dp 51Nod 1006
    vc6 字体设置
    自行车维护大全(zz)
    DirectX 9.0 3D游戏开发编程基础 [书评](zz)
    二维线段树
    latex 引用文献 bib
  • 原文地址:https://www.cnblogs.com/candy99/p/6545270.html
Copyright © 2011-2022 走看看