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 }

浙公网安备 33010602011771号