您的位置:首页 > 其它

nyoj 329 【KMP】

2015-08-07 16:26 260 查看
题目329

题目信息

运行结果

本题排行

讨论区

循环小数

时间限制:3000 ms | 内存限制:65535 KB

难度:1
描述

我们可爱的 c小加 近段儿正在潜心研究数学,当他学习到循环小数这一部分时不是太明白循环体是什么意思(比如说3.23232323的循环体是23、2323、23232323),假设我们现在的循环小数都是严格循环的并且有限的,也就是说不出现2.16666666(循环体为6,长度为1)的情况,只有123123这样的循环出现。给他一个小数,他需要找出最小循环体的长度、循环体和循环的次数,请你帮他解决这个问题。

输入
输入的第一行是t,表示有t组测试数据(t<=100)。
随后的t行,每行都是一个小于10并且大于0的小数(总长度<=200)。

输出对每组输入,输出结果单独成行,输出最小循环体的长度、循环体和出现循环的次数。
样例输入
38.69876987698769870.6665.1


样例输出
4 6987 41 6 31 1 1


之前的一个没有用KMP思想的代码(有Bug)...
题目数据比较弱,此解法有bug 例如输入 0.668668居然输出个1 6 6 ....也是醉了



bugAC代码:

#include<stdio.h>
#include<string.h>
int main()
{
int t,i,j;
char a[222];
int len,c,l;
scanf("%d",&t);
while(t--)
{
scanf("%s",a);
l = strlen(a);
for(i=3;i<l;i++)
{
if(a[i]==a[2])
{
for(j=3;j<i;j++)
if(a[j]!=a[j+i-2])
break;
if(j==i)
break;
}
}
len = i-2;
printf("%d ",len);
for(j=2;j<i;j++)
printf("%c",a[j]);
printf(" %d\n",(l-2)/len);
}
return 0;
}


下面是用KMP算法,无bug,各种测试各种对.
AC代码:

#include<stdio.h>
#include<string.h>
char a[222],s[222];
int next[222];
int len,c;
void getnext()
{
int i=0,j=-1;
next[i]=j;
while(i<len)
{
if(j==-1||s[i]==s[j])
{
i++,j++;
next[i]= j;
}
else
j = next[j];
}
if(len%(len-next[len])==0)
c=len/(len-next[len]);//循环次数
}
int main()
{
int t,l,i,j;
scanf("%d",&t);
while(t--)
{
memset(s,'\0',sizeof(s));
scanf("%s",a);
len=strlen(a);
for(i=2,j=0;i<len;i++,j++)
s[j] = a[i];
len-=2;
getnext();
l = len/c; //循环节长度
printf("%d ",l);
for(i=0;i<l;i++)
printf("%c",s[i]);//循环节
printf(" %d\n",c); //次数
}
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: