2018/10/17 膜你赛 day1T2 周期 60分做法

版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/83152532

题目:

题目描述
老虎和蒜头是好朋友。

中秋节时,老虎收到了一个长度为 nn 的由小写字母构成的串 SS,老虎想要和蒜头一起分享这份喜悦。蒜头当然和老虎的想法不同,虽然蒜头也认为这很有意思,但蒜头更关心的是,如果我们现在可以在 SS 中修改一个字符,那么所有可能的周期长度是多少?

一个长度 1≤T<n1≤T<n 被称为字符串 SS 的周期,当且仅当对任意 1≤i≤n−T1≤i≤n−T ,都有 Si=Si+TSi=Si+T 。

输入格式
共一行,一个长度为 nn 的,只由小写字母构成的串 SS 。

输出格式
输出共两行。在第一行你应当输出可能的周期长度的个数 mm。不妨假设 c=⌈m105⌉c=⌈m105⌉ ,而所有可能的周期长度升序排列后为 l1,l2,,lml1,l2,,lm ,那么你应当输出 lc,l2c,,l⌊mc⌋clc,l2c,,l⌊mc⌋c 。

样例数据
样例一
input
abaabac
output
3
3 5 6
数据范围及限制
对于 100% 的数据,1≤n≤1071≤n≤107 。

对于 20% 的数据,n≤100n≤100 。

对于 40% 的数据,n≤2000n≤2000 。

对于 60% 的数据,n≤20000n≤20000 。

对于 80% 的数据,n≤5×105n≤5×105 。

对于另外 10% 的数据,字符串中只含a,b两种字符。

时间限制: 1s

空间限制: 512MB

思路:
60分的话就是n^2做法。
枚举周期,然后暴力判断就好了。
要注意要修改时不能只标记,要真的修改,不然会爆0。
还要注意第一段就要修改的情况,不考虑只有20分。

代码:

//by juruoZAR
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

#define maxn 20000
#define read(x) scanf("%d",&x);

int n;
char a[maxn+5];
char b[maxn+5];
int ans[maxn+5],cnt=0;

int main() {
	scanf("%s",a+1);
	n=strlen(a+1);

	for(int i=1;i<=n;i++) b[i]=a[i];
	for(int i=1;i<n;i++) {
		int s=0;
		for(int j=1;j<=n;j++) a[j]=b[j];
		for(int j=1;j<=n-i;j++) {
			if(a[j]!=a[j+i]) {
				s++;
				if(s>=2) goto END;
				a[j+i]=a[j];
			}
		}
		ans[++cnt]=i;
		continue;
		END:;
		s=0;
		for(int j=1;j<=n;j++) a[j]=b[j];
		for(int j=1+i;j<=n-i;j++) {
			if(a[j]!=a[j+i]) {
				goto FLAG;
			}
		}
		for(int j=1;j<=i;j++) {
			if(j+i>n) break;
			if(a[j]!=a[j+i]) s++;
		}
		if(s<2) ans[++cnt]=i;
		FLAG:;
	}
	
	int c=(cnt-1)/(1e5)+1;
	
	printf("%d\n",cnt);
	for(int i=1;i*c<=cnt;i++) printf("%d ",ans[i]);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/rabbit_ZAR/article/details/83152532