Tokitsukaze and Duel

9 篇文章 0 订阅

传送门

题意:给你一个n和k,在给你一个由0和1构成的长度为n的字符串,每次操作你可以选择一个长度为k的连续子串,然后将其改变成相同颜色,先将字符串改成相同颜色的人获胜

题解:当n<=k+1时,先手可以直接翻折成同一颜色,属于先手必胜,对于n>2*k时,如果先手不能通过一次操作取得胜利,那之后就不会有人获胜,因为如果先手不能一次取得胜利,那至少需要两步获胜,当n>2*k时,先手总能找到一种方法将步数增加或者保持不变,对于后手同理,当n==k+2时,如果左右两边颜色相同或者有一边从端点颜色数量大于等于n-k那么对于先手都可以一次取完或者俩端点颜色相同,反之如果取不完那对于后手1来说是必胜的,当n>k+2时,先手必胜的判断是一样的,只是俩端点的长度1要大于等于n-k,当先手不能取得必胜时,先手的最佳策略一定是从中间取,然后然俩边颜色不一样或者中间段颜色与两边不同,这样就可以避免后手必胜,但是如果不能达到,那后手就是必胜,如果先手达到了后手不能赢的情况,那对于后手来说,自己采取最优策略已经不能获胜那必然可以通过将先手翻折的那一段翻折成相同颜色以达到先后手置换,最后陷入到谁都无法获胜的局面;

AC代码:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
#include<iostream>
#include<math.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
const int maxn1=1e9;
int read(){
    int x=0,w=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')w=0,ch=getchar();
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
char x[maxn];
int main( )
{
    int n=read(),k=read();
    scanf("%s",x);
    if(n<=k+1){
        printf("tokitsukaze\n");
        return 0;
    }
    else if(n==k+2){
        if(x[0]!=x[n-1]){
            printf("quailty\n");
            return 0;
        }
        else{
            printf("tokitsukaze\n");
            return 0;
        }
    }
    int l=1,r=n-2;
    for(;l<n-1;l++)
        if(x[l-1]!=x[l])
        break;
    for(;r>0;r--)
        if(x[r]!=x[r+1])
        break;
    if(l-1>r){
        printf("tokitsukaze\n");
        return 0;
    }
    if(n>2*k){
        int num=l+n-r-1;
        num=n-num;
        if(x[0]==x[n-1]&&num<=k||k+(n-r-1)>=n||k+l>=n){
            printf("tokitsukaze\n");
            return 0;
        }
        else{
            printf("once again\n");
            return 0;
        }
    }
    else{
        int num=l+n-r-1;
        num=n-num;
        int num1=n-r-1+1,num2=l+1;
        num1=n-num1,num2=n-num2;
        if(x[0]==x[n-1]&&num<=k||k+(n-r-1)>=n||k+l>=n){
            printf("tokitsukaze\n");
            return 0;
        }
        else if(num1<=k&&num2<=k){
            printf("quailty\n");
            return 0;
        }
        else{
             printf("once again\n");
            return 0;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值