zoukankan      html  css  js  c++  java
  • Codeforces Round #102 (Div. 1) D Help Shrek and Donkey 2

    题目链接:Help Shrek and Donkey 2

    题意:一个 n×m 的战场,每行中最多由两个士兵,且只能在同一行种移动。两个玩家,每次每个人可最多选择 k 个自己士兵前进或者撤退(向敌人的方向为前进,向自己的方向为后退),选中的士兵可以移动任意距离,但至少移动 1。当某一方不能移动的时候就为输掉,问这次博弈中谁胜谁负或者平局。

    题解:这可以看成一个Moore’s Nim-k。特殊情况特判掉,只需要考虑每一行都有双方的士兵个一个的情况,因为玩家双方都是采取最优策略,假设某一方采取撤退进入必胜态,则另一方可以采取进攻相同的距离到达一开始的状态,所以只用考虑双方都会进攻即可。如此一来,每一堆的数目就是双方士兵之间的距离,由此就成为了一个Moore’s Nim-k了。

    Moore's Nim-k游戏(抄自网络)

      n 堆石子,每次可以从最多 k 堆中取任意多石子,无法拿石子的人输。

      结论为:把每堆石子的石子数用二进制表示,统计每个二进制位上 1 的个数,若每一位上 1 的个数全为 (k+1) 的倍数,则必败,否则必胜。

    证明如下:

      首先,全0为必败态

      对于任何一个二进制位 1 的数目,每次最多改变为 k 。(k+1) 的倍数经过操作后不可能成为 (k+1) 的倍数,同时任意非 (k+1) 的倍数可以经过操作后成为 (k+1) 的倍数,所以所有二进制位 1 的个数之和均为 (k+1) 的倍数时为必败态。

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,k;
    char s[105][105];
    
    int num[105];
    
    void solve(){
        for(int i=0;i<n;i++){
            int posG=-1,posR=-1;
            for(int j=0;j<m;j++){
                if(s[i][j]=='G') posG=j;
                if(s[i][j]=='R') posR=j;
            }
            if(posG==-1||posR==-1) num[i]=0;
            else num[i]=abs(posG-posR)-1;
        }
        for(int i=0;i<=10;i++){
            int res=(1<<i);
            int sum=0;
            for(int j=0;j<n;j++){
                sum+=(num[j]/res)%2;
            }
            if(sum%(k+1)){
                printf("First
    ");
                return;
            }
        }
        printf("Second
    ");
    }
    
    int main(){
        cin>>n>>m>>k;
        int all1=0,all2=0,flag=0;
        for(int i=0;i<n;i++){
            cin>>s[i];
            int num1=0,num2=0;
            for(int j=0;j<m;j++){
                if(s[i][j]=='G') num1++;
                else if(s[i][j]=='R') num2++;
            }
            if(num1==0&&num2!=0&&num2!=m) all2++;
            if(num1!=0&&num2==0&&num1!=m) all1++;
        }
        if((all1==0&&all2!=0)){
            printf("Second
    ");
            return 0;
        }
        else if(all1!=0&&all2==0){
            printf("First
    ");
            return 0;
        }
        else if(all1!=0&&all2!=0){
            printf("Draw
    ");
            return 0;
        }
    
        solve();
    
        return 0;
    }
  • 相关阅读:
    vue之$nextTick详解
    vue动态组件,运用以及效果选项卡的运用
    深度解析vue之组件之间传值调用方法的奇淫技巧
    关于vuex模块化深层理解实例
    vue效果之改element的el-checkbox-group多选框组为单选可取消的单选框(样式还是多选框的样式)
    vue-div,文字无限滚动效果
    new webpack.ProvidePlugin vue模块化的全局引用
    实践开发:vue框架重点知识分析
    前端工程化,组件化,模块化,层次化
    开发中的细节整理
  • 原文地址:https://www.cnblogs.com/N-Psong/p/10249767.html
Copyright © 2011-2022 走看看