PAT L1-046 整除光棍 光棍当然不是单身汪呢
首先,先來看題目吧:
這里所謂的“光棍”,并不是指單身汪啦~ 說的是全部由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)。
輸出格式:
在一行中輸出相應的最小的s和n,其間以1個空格分隔。
輸入樣例:
31
輸出樣例:
3584229390681 15
我發誓確實有認真的讀題啊,我一心想,不就是太大了嘛,這還不簡單,我就直接定義為long long夠大了吧,但事實是那確實太大了,long long類型變量都不夠存,先貼上一段錯誤代碼,以示警告!!!!!!
#include<stdio.h> #include<math.h> int main() {long long x;long long su = 1;int n = 0;scanf("%lld",&x);//注意小于x一定不能整除,建議把su 先進位到比x大再說if (x==1){printf("1 1");return 0;}while (su < x){n++;su += pow((double)10,n);}while (1){if (su % x == 0){printf("%lld %d",su/x,n+1);break;}else{n++;su += pow((double)10,n);}}return 0;}這里就錯錯錯大了,當我輸入比較小的數的時候可以出結果,但輸個大點的,題目要求的可是<1000
自然就可能很大很大了,看來是我低估了這個題目啊。
看來不能讓他一直進位啊。不然數字就超了范圍啊,自然就溢出了啊。
然后我在進位的時候是用pow函數進位的,其實這樣進位你會忽略掉一個很重要的地方,就拿示例輸入輸出來做個演示,一下就明白,你也會很理解了,剛開始也想了很久,終于給想明白了。
3584229390681 * 31 = 111111111111111
第一步,先找一個比x稍微大點的,這里x=31,自然比31大的就是111了,然后除于x,就得到了最高位 3
第二步 找到111 / 31 的余數 是18,然后第二位該怎么取呢,想一下 把第四位的1給落下來不就可以了嘛;于是 求第二位呢 就是 用(余數 10 +1)/x = (1810+1)/31 =5
第三步,重復第二步就可以。找到 8,4…1;
再來畫個圖理解一下:
!哈哈哈,后面就沒畫了,懂那個意思就可以了
然后來段修改之后正確的代碼`
雖然我前面進位還是用的pow函數,但注意到后面變成了s*10+1了,這也上面的描述一致哦。
建議都寫成一樣的,更加簡潔。
最后再總結一下子:
1. 不要低估題目中說他很大,他說很大就真的很大,如果你要堅持把很大的數存進去,程序也一定會錯誤。在現實生活中同樣如此,總之就是小心溢出。
2. 上述的解題思想我認為就是把他細分,不要把他累計成很大的數。這在以后的做項目時,也是一個很好的思想,分而治之
3. 記住,不要放棄。
哈哈哈,又是一篇博客,歡迎各位大佬指正,感激不盡,希望有人喜歡我的博客,昨天發的那篇還沒人看呢。不過沒關系,沒人看我也發,哈哈哈,因為有太多的疑惑了。記住,不要放棄。
總結
以上是生活随笔為你收集整理的PAT L1-046 整除光棍 光棍当然不是单身汪呢的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鹰的精神
- 下一篇: 专家访谈:Flex技术对web开发的影响