2018 牛客多校第三场 E-Sort String

具体题解看这里。。:https://www.nowcoder.com/discuss/88445?type=101&order=0&pos=2&page=0

 

这里主要学到的是求字符串最小循环节的方法

       最小循环节的定义(不是知道对不对自己根据别人的程序推测的orz):

        如果st1是st的最小循环节,那么 st 是st1不断重复形成的字符串t的某个长度大于st1前缀  

       最小循环节长度x=len-next[len];

 

首先如果出现字符串首尾相连之后,从不同位置出发绕一圈得到的串一样,那么字符串肯定是由某个最小的循环节不断重复得到的

那么len%x==0可以被分成 x组

不然所有的si都不相等

 

#include<bits/stdc++.h>
using namespace std;

char st[1000009];
int nex[1000009];

void getnext(int len){
   int j=0,k=-1;
   nex[0]=-1;
   while(j<len){
   	 if (k==-1||st[j]==st[k])
   	      nex[++j]=++k;//找到了next[j]的值 
      else
          k=nex[k];  //k继续向前找 
   }	
}
int main(){
	scanf("%s",st);
	int len=strlen(st);
	getnext(len);
	int x=len-nex[len]; //x最小循环节长度 
//	printf("%d\n",x);
	
	if (len%x!=0){
		 cout<<len<<endl;
		 for (int i=0;i<len;i++)printf("1 %d\n",i); 
		
	}else//st是由循环节循环len/x次形成的 
	{    printf("*%d\n",x);
		 for (int i=0;i<x;i++){
		 	   printf("%d",len/x);
		 	   for (int j=i;j<len;j+=x)
		 	     printf(" %d",j);
		 	   printf("\n");
		 }
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值