【USACO 2.4.5】分数化小数

【描述】

写一个程序,输入一个形如N/D的分数(N是分子,D是分母),输出它的小数形式。 如果小数有循环节的话,把循环节放在一对圆括号中。

例如, 1/3 =0.33333333 写成0.(3), 41/333 = 0.123123123... 写成0.(123), 用xxx.0 等表示整数。 典型的转化例子:

1/3 = 0.(3)
22/5 = 4.4
1/7 = 0.(142857)
2/2 = 1.0
3/8 = 0.375
45/56 = 0.803(571428)

PROGRAM NAME fracdec

【格式】

INPUT FORMAT

单独的一行包括被空格分开的N和D(1 <= N,D <= 100000)。

OUTPUT FORMAT

按照上面规则计算出的小数表达式.如果结果长度大于76,每行输出76个字符.

【分析】

直接模拟除法就行了(长除法),不得不说有一点麻烦。

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 const int maxn=1000000;
 8 using namespace std;
 9 int point=1,vis[maxn+100];//vis同时记录a在ans中的位置 
10 int ans[maxn],zf=0;//zf是字符输出统计 
11 void cnt();
12 int main()
13 {
14     int a,b,i;
15     //文件操作
16     freopen("fracdec.in","r",stdin);
17     freopen("fracdec.out","w",stdout);
18     memset(vis,0,sizeof(vis));//初始化
19      
20     scanf("%d%d",&a,&b);
21     if (a%b==0) {printf("%.1lf",(double)a/b);return 0;}//可以直接整除
22     
23     printf("%d.",a/b);cnt();
24     int temp=a/b;if (temp==0) cnt();
25     while (temp!=0) {cnt();temp/=10;}//顺便统计字符 
26     //printf(" %d\n",zf);
27     a=a%b;
28     vis[a]=1;
29     ans[point++]=a;
30     for (i=2;;i++)
31     {
32         a=(a*10)%b;
33         ans[point++]=a;
34         if (vis[a]) break;//出现重复值 
35         vis[a]=i;
36     }point--;
37     
38     for (i=1;i<vis[ans[point]];i++) {cnt();printf("%d",(ans[i]*10)/b);}//输出重复值之前的部分 
39     if ((ans[vis[ans[point]]]*10)/b==0 && vis[ans[point]]==point-1) return 0;//重复值为0 
40     cnt();printf("(");
41     for (i=vis[ans[point]];i<point;i++) {cnt();printf("%d",(ans[i]*10)/b);}
42     cnt();printf(")");
43     //printf("\n%d",zf);
44     return 0;
45 }
46 void cnt()
47 {
48      //已经输出了zf个字符 
49      if (zf==76) {printf("\n");zf=0;}
50      zf++;
51 }

 

posted @ 2014-06-22 19:26  TCtower  阅读(553)  评论(0编辑  收藏  举报