UVA202-Repeating Decimals
阿新 • • 發佈:2018-10-26
用例 bool 表示 tar std 小數點 can number 註意點
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 }
UVA202-Repeating Decimals