【Codeforces Gym】 100162B Circle of Stones

本文介绍了一种解决颜色石头问题的方法。该问题要求从一圈有颜色的石头中取出连续的一段,使得取出的部分中没有相邻两个石头颜色相同,并探讨了所有可能的长度下能否找到符合条件的石头序列。

Discription

题目大意是给一圈有颜色的石头,问对于所有长度是否可以拿去该长度的石头(连续),使得不存在相邻两个石头颜色相同。

Solution

首先是那些原本就贴在一起的……还说啥……拆了
这样就可以拆成很多段(也有可能一个都没)
同时,还可以把环翻倍拆成链
(反正拆成链就对了)

那么对于每一段,再从中取出一段的时候,只有保证头尾不同即合法。
那如果说长度为len-k的答案不存在,也就意味着取不出一个长度为k的串,使得其头尾不同。
换句话说,就是这一段所有的字符,都和其后第k个字符相同。

那么对于本段,不存在长度为k的合法串,只需检查一下这一段错k位后是否相等。
(我用的hash,枚举也是特别暴力的枚举方式,完全没有优化,不过貌似数据也比较随机)

#include<stdio.h>
#include<cstring>
#include<algorithm>
#define x 233
#define mod 1000000007
#define N 1000005

using namespace std;
typedef long long ll;

bool f[N];
char s[N<<1];
int p[N<<1],T;

int main()
{
    while (~scanf("%s",s+1))
    {
        memset(f,0,sizeof(f));
        int len=strlen(s+1);
        for (int i=1;i<=len;i++) s[i+len]=s[i];
        for (int i=1,k=1;i<=len<<1;i++,k=(ll)k*x % mod) p[i]=(p[i-1]+(ll)(s[i]-'a'+1)*k) % mod;
        for (int l=1,i=1,up=min(i-l,len);i<=len<<1;i++,up=min(i-l,len)) if (s[i]==s[i-1] || i==len<<1)
        {
            for (int t=1,k=1;t<=up;t++,k=(ll)k*x % mod) if ((p[i-1]-p[l+t-2]+mod) % mod!=(ll)k*(p[i-t]-p[l-1]+mod) % mod) f[t]=1;
            l=i;
        }
        printf("Case %d: ",++T);
        for (int i=len;1<i;i--) putchar(f[i]?'1':'0');
        puts("1");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值