zoukankan      html  css  js  c++  java
  • Codeforces Round #721 (Div. 2) B2. Palindrome Game (hard version) (博弈)

    传送门

    题意

    给定一个字符串,A和B轮流操作,A是先手;
    每个人可以有如下的两种操作:
    (1:)将字符串中某个位置的(0)换成(1),代价为(1)
    (2:)将整个字符串翻转,代价为(0)
    其中操作(2)的条件为:当前的字符串不是回文字符串并且上一次并没有执行过该操作
    当字符串变为全(1)字符串时,游戏结束。代价小的获胜。

    思路

    先考虑(easy)版本,也就是开始都是回文字符串时,输赢跟(0)的个数有关:

    • 如果当前有奇数个(0)时,由于是回文字符串,中心轴的位置一定为(0),假设为(0000000)
      为了方便计算代价,假设先手改变的(1)(2)来表示,后手改变的(1)(3)来表示
      先手会将中心轴位置的(0)变为(1),这样先手代价为(1),字符串变为(0002000)
      由于当前字符串仍旧满足回文串,所以后手只能选择操作(1),后手代价为(1),字符串变为(0032000)
      接下来的操作中,先手都在跟后手对称的位置进行操作(1),这样每次后手操作时,字符串都为回文串,所以只能执行操作(1)
      当字符串变为(3332220)时,轮到先手操作,先手可以执行操作(2),这样字符串变为(0222333),后手只能再执行操作(1),字符串变为(3222333),最后先手的代价为(3),后手的代价为(4),先手赢。
    • 如果当前有偶数个(0)时,假设为(000000)
      先手只能执行操作(1),字符串变为(002000);后手也在对称的位置执行操作(1),这样类似于上一种情况,先手永远不会遇到回文串的情况,也就无法执行操作(2)
      当字符串变为(322330)时,后手翻转字符串,得到(033223),先手执行操作(1),得到(233222),最后先手的代价为(4),后手的代价为(2),后手赢。
    • 但是当只有1个0时,先手只能进行操作(1),后手赢。
      (hard)版本如何考虑呢。

    首先我们可以知道将原串变为回文串的代价,记作(sum)

    • 如果(sum>=2)的话,先手必赢:假设字符串为(111000),由于字符串不是回文字符串,所以先手可以先执行操作(2),后手只能执行操作(1),直到游戏结束。
    • 如果(sum==0)的话,就按照回文串的情况写
    • 如果(sum==1)的话,考虑0的个数:如果只有2个0的话是平局,否则就是先手赢。
      如果只有两个0说明中心轴一定为0,假设字符串为100,那么先手可以执行操作2,变为001,后手只能执行操作1,变为021,先手执行操作1,变为321,是平局;
      否则的话,1101,先手执行操作2,后手执行操作1,先手代价小,先手赢。

    代码

    const int maxn =1e5+7;
    char s[maxn];
    void solve(){
    	int n=read;
    	cin>>s+1;
    	int cnt=0,sum=0;
    	for(int i=1;i<=n;i++)
    		if(s[i]=='0') cnt++;
    	for(int i=1;i<=n;i++)
    		if(s[i]=='1'&&s[n-i+1]=='0') sum++;
    	///cout<<sum<<" "<<cnt<<endl;
    	if(sum==0){
    		if(cnt==1){
    			cout<<"BOB"<<endl;
    		}
    		else if(cnt%2){
    			cout<<"ALICE"<<endl;
    		}
    		else puts("BOB");
    	}
    	else if(sum>=2){
    		puts("ALICE");
    	}
    	else if(sum==1){
    		if(cnt==2) puts("DRAW");
    		else puts("ALICE");
    	}
    }
    
    int main() {
    	int T=read;
    	while(T--){
    		solve();
    	}
    	return 0;
    }
    
    

    参考

  • 相关阅读:
    4.父类私有属性和方法
    3.单继承和方法的重写
    2.Python封装练习及私有属性
    1.Python面向对象基础
    6.类与对象、封装、构造方法
    5.数组
    4.方法
    3.流程控制语句
    结构型模式和物理视图,模型管理试图的总结
    创建型模式和关于状态视图、活动视图、交互视图的总结
  • 原文地址:https://www.cnblogs.com/OvOq/p/14792907.html
Copyright © 2011-2022 走看看