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");
}
}

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

被折叠的 条评论
为什么被折叠?



