1. 程式人生 > 其它 >PTA 翁愷 7-42 整除光棍

PTA 翁愷 7-42 整除光棍

這裡所謂的“光棍”,並不是指單身汪啦~ 說的是全部由1組成的數字,比如1、11、111、1111等。傳說任何一個光棍都能被一個不以5結尾的奇數整除。比如,111111就可以被13整除。 現在,你的程式要讀入一個整數x,這個整數一定是奇數並且不以5結尾。然後,經過計算,輸出兩個數字:第一個數字s,表示x乘以s是一個光棍,第二個數字n是這個光棍的位數。這樣的解當然不是唯一的,題目要求你輸出最小的解。

提示:一個顯然的辦法是逐漸增加光棍的位數,直到可以整除x為止。但難點在於,s可能是個非常大的數 —— 比如,程式輸入31,那麼就輸出3584229390681和15,因為31乘以3584229390681的結果是111111111111111,一共15個1。

輸入格式:

輸入在一行中給出一個不以5結尾的正奇數x<1000)。

輸出格式:

在一行中輸出相應的最小的sn,其間以1個空格分隔。

輸入樣例:

31
結尾無空行

輸出樣例:

3584229390681 15
整體思路:
顯然這裡按照傳統的大數除法是行不通的,儲存空間不夠,資料過大也會產生精度丟失,只能另闢捷徑了。
在傳統的除法之中,比如144 / 6 ,先判斷 1 < 6 ,無法用1除,改用14(14=1*10+4)除,14 / 6 = 2(整數除法),餘數為2(不為0,繼續進行操作),
繼續用2*10+4=24,24除以6,商為4,餘數為0結束操作。
可以巧妙地採用模擬除法,被除數s(s不是固定為某個值,初始值為第一位數,本題為1),除數x,餘數為y。第一步先判斷s是否大於等於x,滿足則開始相除,
不滿足則s = s * 10 +1直至s >= x(這裡的1為第二位數,僅僅是本題為1)然後取餘,y = s / x;利用整數除法得出第一位數s / x;類比傳統除法,此時的
s = s * 10 + 1;然後判斷y是否為0,為0則結束操作,否則繼續迴圈。
整體程式碼:
#include <stdio.h>

int main (void){
    int x = 0,y = 1;
    int s = 1;
    int count = 1;
    scanf ("%d",&x);
    while(s < x)
    {
        s = s * 10 + 1;
        count++;
    }
    while (y != 0)
    {
        y = s % x;
        printf("%d",s / x);
        s = y * 10 + 1;
        count
++; } printf(" %d",count - 1); return 0; }

討論:

  • y=0後到結束迴圈之前,count多加了一次,所以最後輸出時要減一,也可以在輸出s/x後面加上判斷語句跳出迴圈
  • 模擬除法非常巧妙,與陣列結合可以運算非常大的數。