UVA202|WF1990 - Repeating Decimals

题意:给定n,m求n/m小数部分的最小循环节

解析:昨天集训做山东省赛,正好和一道题类似(Grade Point Average)。都是模拟长除法的

 

 

找到循环的起始和结尾,可以用map<pair,int>来存储

注意:格式处理要小心,有点复杂

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5+10;
 4 int unit;
 5 int decimal[N];
 6 typedef pair<int,int>  pii;
 7 map<pii,int>mp;
 8 int n,m;
 9 
10 void cal(int n,int m)
11 {
12     mp.clear();
13     int r;//余数 
14     int last;//循环的起始位置 
15     int cnt;//长度 
16     int now;//循环的结尾 
17     unit=n/m;//小数点前的数 
18     if(n>=m)n-=m*unit;
19     for(int i=1;i<=N;i++)
20     {
21         if(n==0)//n==0特判 
22         {
23             decimal[i]=0;
24             r=m;
25             if(mp[{decimal[i],r}]>0)
26             {
27                 now=i;
28                 last=mp[{decimal[i],r}];
29                 cnt=i-mp[{decimal[i],r}];
30                 break;
31             }
32             else mp[{decimal[i],r}]=i;
33         }
34         else
35         {
36             n*=10;
37             decimal[i]=n/m;
38             r=n%m;
39             n-=m*(n/m);
40             if(mp[{decimal[i],r}]>0)//如果找到循环 
41             {
42                 now=i;
43                 last=mp[{decimal[i],r}];
44                 cnt=i-mp[{decimal[i],r}];
45                 break;
46             }
47             else mp[{decimal[i],r}]=i;
48         }
49     }
50     printf("%d.",unit);
51     for(int i=1;i<last;i++) printf("%d",decimal[i]);
52     printf("(");
53     if(cnt<=50)
54     {
55         for(int i=last;i<now;i++)printf("%d",decimal[i]);
56     }
57     else
58     {
59         for(int i=last;i<last+50;i++)printf("%d",decimal[i]);
60         printf("...");
61     }
62     printf(")\n");
63     printf("   %d = number of digits in repeating cycle\n\n",cnt);
64 }
65 
66 int main()
67 {
68     while(scanf("%d%d",&n,&m)!=EOF)
69     {
70         printf("%d/%d = ",n,m);
71         cal(n,m);
72     }
73     return 0;
74 }

 

 

 

 

 

 

 

 

posted @ 2021-05-13 20:31  Kaoru1120  阅读(60)  评论(0)    收藏  举报