【算法競賽入門經典】習題3-8循環小數(Uva202)

一、題目

偷個懶,題目在這裏Uva202
大意就是輸入兩個整數a和b,輸出a/b的循環小數表示以及循環節的長度。

二、解題思路

關鍵在於找循環節,用res來存儲每一次的商,用mod數組來存儲每一次的餘數。在計算小數部分時每次都將上一次的餘數乘十作爲本次的被除數,依次進行下去直到找到某一次的商和餘數在前面出現過,即找到了循環節。
要注意輸出的格式,每個用例最後應該有兩個換行符
具體見代碼及註釋

三、代碼

#include<stdio.h>
int res[3005],mod[3005];//res數組記錄每一次的商,mod數組記錄每一次的餘數 
int main(){
 int a,b;
 while(scanf("%d%d",&a,&b)!=EOF){
  int i=0,j;
  int flag=0;//標記是否找到了循環節 
  printf("%d/%d = %d.",a,b,a/b);//先輸出整數部分 
  while(true){
   res[i]=a/b;
      mod[i]=a%b;
      a=(a%b)*10; //將這次的餘數乘以十作爲下一次的被除數 
      for(j=1;j<i;j++){  //與前面出現的商和餘數進行比較;注意是從j=1,即小數點後進行比較 
       if((res[j]==res[i]) && (mod[j]==mod[i])){ //若餘數和商的組合在前面出現過,則表示出現循環節 
        flag=1; //此時的i爲第二次出現循環節的開頭第一個數字的位置 
        break;
    }
   }
   if(flag){
    break;
   }
   i++;
  }
  for(int k=1;k<j;k++){ //注意到res[0]中存儲的是整數部分 
   printf("%d",res[k]); //輸出小數點後非循環節部分 
  }
  printf("(");
  if(i>50){ //如果要輸出的小數部分位數大於50,就只輸出前50個 
   for(int k=j;k<=50;k++){
    printf("%d",res[k]);
   }
   printf("...)\n");
  }else{
   for(int k=j;k<i;k++){
    printf("%d",res[k]);
   }
   printf(")\n");
  }
  printf("   %d = number of digits in repeating cycle\n\n",i-j); //注意輸出格式,循環節長度前有三個空格,末尾兩個換行符 
 }
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章