Repeating Decimals
大致题意:求一个小数的循环节,并用括号括起来,并求循环节的长度。
具体形式见输出样例。
输出细节:
1.输入两个整型,都<=3000,被除数—非负整数,除数—正整数。
2.如果 整除,则把0作为循环节。(具体看样例)
3.如果循环节>=50,则输出50位后,用…省略。(具体看样例)
Sample Input
76 25
5 43
1 397
0 1
65 90
1 1
112 990
3000 17
2223 13
Sample Output
76/25 = 3.04(0)
1 = number of digits in repeating cycle
5/43 = 0.(116279069767441860465)
21 = number of digits in repeating cycle
1/397 = 0.(00251889168765743073047858942065491183879093198992…)
99 = number of digits in repeating cycle
0/1 = 0.(0)
1 = number of digits in repeating cycle
…
大致思路
见小结。
代码示例
错误代码 shit
(好奇为什么能accept,难道是uva的题的测试数据都是随机的?,恰巧漏过那些通不过的数据)
#include"stdlib.h"
#include"stdio.h"
int main()
{
int x;
int y,i,head,j,find,k,count;
int a[3000],b[3000];//a放余数,b放商
while(scanf("%d %d",&x,&y)==2)
{
head=0;find=1;
printf("%d/%d = ",x,y);
if(x/y!=0)
{
head=x/y;
x=x % y;
}
a[0]=(x*10) % y;
b[0]=x*10 /y ;
for(i=1;i<=y && find;i++)
{
if(a[i-1]==0)
{i++;break;}//这里i++是为了适配其他有循环的情况,和下一个i的注释有关
else a[i]=a[i-1]*10 % y;
b[i]=a[i-1]*10 / y;
for(j=0;j<i;j++)
{
if(a[j]==a[i])
{
find=0;
break;
}
}
}
i--;//跳出循环前i会加1
printf("%d.",head);
if(a[i]==0)
{
for(k=0;k<i;k++)
{
printf("%d",b[k]);
}
printf("(0)\n");
printf("1 = number of digits in repeating cycle\n");
}
else
{
for(k=0; k<j; k++)
{
printf("%d",b[k]);
}
printf("(");
for(count=1; k<i; k++,count++)
{
if(count>=51)
{
printf("...");
break;
}
printf("%d",b[k]);
}
printf(")\n");
printf("%d = number of digits in repeating cycle\n",i-j);
}
}
return 0;
}
代码问题:
不过以下测试用例:
0 1
65 90
1 1
112 990
3000 17
小结
我判断的方法有问题。
当出现重复余数的时候,(以3000/17为例)
first :3000/17=176…8 这个余数必须加入判断。而上面代码遗漏。
second:
被除数 | 除数 | = | 商 | 余数 |
---|---|---|---|---|
3000 | 17 | = | 176 | 8 |
80 | 17 | = | 4 | 12 |
120 | 17 | = | 7 | 1 |
10 | 17 | = | 0 | 10 |
100 | 17 | = | 5 | 15 |
150 | 17 | = | 8 | 14 |
140 | 17 | = | 8 | 4 |
40 | 17 | = | 2 | 6 |
60 | 17 | = | 3 | 9 |
90 | 17 | = | 5 | 5 |
50 | 17 | = | 2 | 16 |
160 | 17 | = | 9 | 7 |
70 | 17 | = | 4 | 2 |
20 | 17 | = | 1 | 3 |
30 | 17 | = | 1 | 13 |
130 | 17 | = | 7 | 11 |
110 | 17 | = | 6 | 8(重复) |
这道题真正的算法是:
看到重复余数,则 开始循环位置 位于,第一个重复余数的下面一行的 商。而 结束循环位置 是第二个重复余数的那一行的商。
注意输出格式。
正确代码
#include"stdlib.h"
#include"stdio.h"
int main()
{
int x,y;
int flag,nocyctie,i,j;
int left[3001],div[3001],scyctie,ecyctie,enddigit,count;
while(scanf("%d%d",&x,&y)==2)
{
flag=1;nocyctie=0;count=0;
for(i=0; i<=y&&flag; i++)
{
if(i==0)
{
div[i]=x/y;
left[i]=x%y;
}
else
{
div[i]=left[i-1]*10/y;
left[i]=left[i-1]*10%y;
}
if(left[i]==0)
{
enddigit=i;
nocyctie=1;
break;
}
for( j=0; j<i; j++)
{
if(left[i]==left[j])
{
scyctie=j+1;
ecyctie=i;
flag=0;
break;
}
else
continue;
}
}
//输出
if(nocyctie)
{
printf("%d/%d = ",x,y);
printf("%d.",div[0]);
for(i=1; i<=enddigit; i++)
{
printf("%d",div[i]);
}
printf("(0)\n");
printf(" 1 = number of digits in repeating cycle\n\n");
}
else
{
printf("%d/%d = ",x,y);
printf("%d.",div[0]);
for(i=1,count=0; i<scyctie&&count<50; i++,count++)
{
printf("%d",div[i]);
}
printf("(");
for(i=scyctie; i<=ecyctie&&count<50; i++,count++)
{
printf("%d",div[i]);
}
if(count==50)
{
printf("...");
}
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n",ecyctie-scyctie+1);
}
}
return 0;
}
代码问题:
不过以下测试用例:
0 1
65 90
1 1
112 990
3000 17
wen
总结:
1.算法要对。
2.专注构思。
3.找一般例子,再思考,可能的特例,再看一看 可能特例 是否应该符合算法(检验自己算法的正确性)。