51nod 欧姆诺姆和项链 1554

题意:

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值