循环小数 UVA 202

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:

被除数除数=余数
300017=1768
8017=412
12017=71
1017=010
10017=515
15017=814
14017=84
4017=26
6017=39
9017=55
5017=216
16017=97
7017=42
2017=13
3017=113
13017=711
11017=68(重复)

这道题真正的算法是:

看到重复余数,则 开始循环位置 位于,第一个重复余数的下面一行的 商。而 结束循环位置 是第二个重复余数的那一行的商。

注意输出格式。


正确代码

#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.找一般例子,再思考,可能的特例,再看一看 可能特例 是否应该符合算法(检验自己算法的正确性)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值