UVA202-Repeating Decimals

2018-10-25-00:20:06

原题链接

题目描述:

本题有多组测试用例,输入一个整数a和一个正整数b,输出a/b的循环小数表示以及循环节的长度。

本题思路:

上来直接模拟除法,保留每一次的余数,每次判断是否遇到相同余数,余数相同时保存两个相同余数在数组里的位置,接着只需要注意输出即可,根据抽屉原理,a/b的余数只能是0~b-1所以计算b+1次必定有余数重复,所以将存储余数的数组开至稍大3000即可。

本题注意点:

我第一次做的时候由于审题不认真直接看了样例就开始写,导致答案错的离谱,错的主要原因在于小数点后面还有不再循环节以内的部分也需要单独输出,还有一个小数是有限循环小数的情况,如果最后一位余数为零则表明该数是有限循环小数。注意输出行中有空行和空格就可以了。

本题感悟:

数学题注意模拟出所有情况之后再进行代码实现,不然就会像这次一样功亏一篑。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int Maxn=3010;
 5 int ans[Maxn];//用一个一维数组储存每次模拟除法之后的余数
 6 bool isFind(int A,int &cnt1,int cnt2){
 7     for(int i=0;i<cnt2;i++)
 8         if(ans[i]==A){
 9             cnt1=i;
10             return true;
11         }
12     return false;
13 }
14 
15 int main()
16 {
17     int a,b;
18     while(scanf("%d %d",&a,&b)==2&&b){
19         memset(ans,0,sizeof(ans));
20         int A=a%b,B=b,cnt1=0,cnt2=0;//两个cnt用来记录第一次出现余数相等的两个位置
21         ans[cnt2++]=A;
22         while(A){
23             A*=10;
24             A%=B;//简单模拟除法,然后保存余数部分
25             ans[cnt2]=A;
26             if(isFind(A,cnt1,cnt2))
27                 break;
28             else cnt2++;
29         }
30         printf("%d/%d = %d.",a,b,a/b);
31         if(!A)
32             for(int i=0;i<cnt2-1;i++)
33                 printf("%d",(ans[i])*10/B);
34         else if(cnt1)
35             for(int i=0;i<cnt1;i++)
36                 printf("%d",(ans[i])*10/B);
37         printf("(");
38         if(A)
39             for(int i=cnt1;i<cnt2;i++){
40                 printf("%d",(ans[i])*10/B);
41                 if(i>=cnt1+49){
42                     printf("...");
43                     break;
44                 }
45             }
46         else printf("0");
47         printf(")\n   %d = number of digits in repeating cycle\n\n",A?cnt2-cnt1:1);
48     }
49     return 0;
50 }

 

posted @ 2018-10-26 00:20  Cruel_King  阅读(230)  评论(0编辑  收藏  举报