1、给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s。求这个过程中比原来的数字小的、相等的、大的数字各有多少。

例如:字符串123,变换过程:123 -> 312 -> 231 -> 123

因为:312>123, 231>123, 123=123

所以答案是:0 1 2

2、令str1=s,str2=s+s,然后str1作为子串,str2作为主串,进行扩展kmp求出str2[i...len2-1]与str1[0...len1-1]的最长公共前缀。当公共前缀==len1时,两个数相等;否则,只须比较公共前缀后的下一个字符就能判断大小了。

注意当中有重复的情况,只有当s有循环节的时候才会出现,先求出s的最小循环节,然后用s的长度除以最小循环节得到循环节的个数,将3个结果都除以循环节个数即可。

3、

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define MaxSize 200005 int _next[MaxSize],extend[MaxSize]; //扩展kmp
//next[i]:x[i...m-1]与x[0...m-1]的最长公公前缀
//extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀
void pre_EKMP(char x[],int m,int _next[]){//m长度
_next[]=m;
int j=;
while(j+<m&&x[j]==x[j+])j++;
_next[]=j;
int k=;
for(int i=;i<m;i++){
int p=_next[k]+k-;
int L=_next[i-k];
if(i+L<p+)_next[i]=L;
else{
j=max(,p-i+);
while(i+j<m&&x[i+j]==x[j])j++;
_next[i]=j;
k=i;
}
}
} void EKMP(char x[],int m,char y[],int n,int _next[],int extend[]){//x子串,m子串长度,y主串,n主串长度
pre_EKMP(x,m,_next);
int j=;
while(j<n&&j<m&&x[j]==y[j])j++;
extend[]=j;
int k=;
for(int i=;i<n;i++){
int p=extend[k]+k-;
int L=_next[i-k];
if(i+L<p+)extend[i]=L;
else{
j=max(,p-i+);
while(i+j<n&&j<m&&y[i+j]==x[j])j++;
extend[i]=j;
k=i;
}
}
}
/*
子串 :a b a b
主串 :a b a b a c
next :4 0 2 0
extend:4 0 3 0 1 0
*/
void GetNext(char t[]){//求next数组
int j,k,len;
j=;//从0开始,首先求_next[1]
k=-;//比较指针
_next[]=-;//初始值-1
len=strlen(t);
while(j<len){
if(k==-||t[j]==t[k]){//指针到头了,或者相等
++j;
++k;
_next[j]=k;//此句可由优化替代
/*优化(求匹配位置时可用)
if(t[j]!=t[k])_next[j]=k;
else _next[j]=_next[k];
//*/
}
else k=_next[k];
}
}
int main(){
char str1[],str2[];//子串,主串
int i,j,len1,len2;//子串长度,主串长度
int T;
int sumL,sumE,sumG;
scanf("%d",&T);
for(i=;i<=T;++i){
sumL=sumE=sumG=;
scanf("%s",str1);
strcpy(str2,str1);
strcat(str2,str1);
len1=strlen(str1);
len2=strlen(str2);
EKMP(str1,len1,str2,len2,_next,extend);
for(j=;j<len1;++j){
if(extend[j]==len1)++sumE;
else if(str2[j+extend[j]]<str1[extend[j]])++sumL;
else ++sumG;
}
GetNext(str1);
int repetend=len1-_next[len1];//最小循环节
int numR;//循环节的个数
if(len1%repetend==)numR=len1/repetend;
else numR=;
printf("Case %d: %d %d %d\n",i,sumL/numR,sumE/numR,sumG/numR);
} return ;
}

最新文章

  1. 工作中遇到的一个多线程下导致RCW无法释放的问题
  2. fragment 监听返回
  3. display:inline-block的坑
  4. ref游标(动态游标)
  5. Android开发之自定义圆形的ImageView的实现
  6. JavaScript- 省市联动代码
  7. python 之路,Day11(上) - python mysql and ORM
  8. telnet如何操作Memcached缓存系统?
  9. 亲测VS2010纯静态编译QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序(图文并茂,非常详细)
  10. pathload --有效的网络带宽估计方法
  11. BI中事实表和维度表的定义
  12. [原创]MySQL数据库忘记root密码解决办法
  13. poj2479 最大子段和
  14. Linux系统下一个冷门的RAID卡ioc0及其监控mpt-status
  15. python函数之基础
  16. 【Excel】SUMIF 或用 筛选器 实现挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加
  17. Django学习手册 - 正则URL路由配置/路由分发
  18. 002-Spring Cloud 功能简介
  19. HDU 3472 混合图欧拉回路 + 网络流
  20. C语言----&lt;另类&gt;神奇的&quot;Hello World!&quot;

热门文章

  1. unittest多线程执行用例
  2. POJ-Crazy tea party,很好的一道数学题~~~
  3. iOS-runtime-根据类名推送到任意控制器,且实现属性传值
  4. E题
  5. BZOJ——4195: [Noi2015]程序自动分析
  6. Generate Parentheses(组合,回溯)
  7. MongoDB学习day08--Mongoose索引、Mongoose内置方法、扩展Mongoose Model的静态方法和实例方法
  8. MongoDB学习day05--MongDB开启权限验证,创建用户
  9. 转:SIP相关的RFC文档索引
  10. FIREDAC保存ORACLE的BLOB字段数据