题意:
1554 欧姆诺姆和项链
1.0 秒 131,072.0 KB 80 分 5级题
有一天,欧姆诺姆发现了一串长度为n的宝石串,上面有五颜六色的宝石。他决定摘取前面若干个宝石来做成一个漂亮的项链。
他对漂亮的项链是这样定义的,现在有一条项链S,当S=A+B+A+B+A+…+A+B+A的时候是漂亮的,这儿A,B是一些宝石串,“+”表示连接操作。S中有k+1个A和k个B组成。A和B可能是空串。
现在给出宝石串,问怎么切前几个才能得到一个漂亮的宝石项链。他切下来之后不会改变宝石的顺序。
样例解释:
在这个样例中前6个可以组成漂亮的串( A="", B=“bca”)。前7个也可以(A=“b”, B=“ca”)。
输入
单组测试数据。
第一行有两个整数n, k (1≤n,k≤1 000 000),表示宝石串原始的长度和在上文中提到的参数k。
第二行有n个由小写字母组成的串,表示原始宝石串。
输出
输出一行有n个01组成的字符串。第i(1≤i≤n)个位置是1的时候表示前i个宝石可以组成漂亮的宝石项链。
输入样例
样例输入1
7 2
bcabcab
输出样例
样例输出1
0000011
思路:
(1)首先,我们还是先明确题意好了,给了一个长度为n的字符串,现在我们可以把字符串切割为两个串,分为1~i和i+1~n两个字符串,问1~i这个串是不是漂亮的,漂亮满足的条件S=A+B+A+B+A+…+A+B+A。如果1~i这个串是漂亮的,那么ans[i] = 1,否则ans[i] = 0
(2)如果1~i这个串可以表示为SSSSSSSSSSS…,一共有num个,分成k份,每份有num / k个,会多余出来num % k个,A中S的数量就是num % k,B可以是空串,说明满足num/k-num%k >= 0。
(3)如果1~i这个串可以表示为SSSSSSSSSST…,假设前一部分为T,后一部分为D,那么原串就变成了TDTDTDTDTDTDTDTDT,那么划分方式就是TDT/DTD/TDT/DTD…,那么B串一定不为空,还是总的循环节的数量为num,分成k份,每份有num / k个,剩下的就是A的数量num % k,说明就要满足num / k - num % k > 0
代码实现:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
int n,k;
char s[maxn];
int len;
int nex[maxn];
void getNext(){
int k = -1; int j = 0;
nex[0] = -1;
while(j < len){
if(k == -1||s[k] == s[j]){
nex[++j] = ++k;
}
else k = nex[k];
}
}
int main(){
scanf("%d%d",&n,&k);
scanf(" %s",s);
len = strlen(s);
getNext();
for(int i = 1;i <= len;i++){
int tmp = i - nex[i];
if(i % tmp == 0){
if((i / tmp) / k - (i / tmp) % k >= 0){
printf("1");
}
else printf("0");
}
else{
if((i / tmp) / k - (i / tmp) % k > 0){
printf("1");
}
else printf("0");
}
}
printf("\n");
return 0;
}