之江學院 K: qwb與小數(思維求A/B第n位小數)
阿新 • • 發佈:2018-12-31
記得不久前的一場實驗室收錢大賽中,出現了一個六位有效數字,以及迷之坑點0 , 0 的資料,jnf這次吸取了教訓,所以。。。他準備再卡一下小數點。當然此題不會太難,jnf友情的提示學弟學妹們,這題。。是很簡單(^_^)的!
jnf遇到了一個問題:將分數a/b化為小數後,小數點後第n位的數字是多少?
因為這是第一道題,我們已經不指望你能夠幫上他了。。。
當然如果你們暴力過了,算我jnf輸!
多組測試資料,處理到檔案結束。(測試資料<=10組)
每組測試例包含三個整數a,b,n,相鄰兩個數之間用單個空格隔開,其中0 <= a <1e8,0 < b <= 1e8,1 <= n <= 1e8。
對於每組資料,輸出a/b的第n位數,佔一行
1 2 1
1 2 2
5
0
該題目是求a/b的小數點後的第n位數字是啥?面對該題目,你首先想到的是按照題目的思路一步一步的走向錯誤,第一步根本就不能先a/b,
因為如果轉換成double型的小數,在求第n位小數是什麼的時候,會出現精度的誤差:
C語言裡面,預設%f是小數點後6位,如果想小數點後面16位,寫成%.16lf
不會自動四捨五入的,double是一個近似值,通常沒有辦法做的很精確.
通常能精確到小數點後面5,6位,也就是說超過5,6位了可能就不準了。
所以這個題目需要轉化思路,即將等式兩邊同時乘以10^n,即可得到,接下來我的思路是這樣的:求a*(10^n),然後對10取餘,即可得到第n位小數,但是wa了,我還不知道為什麼。
經過斌爺的指導我終於找到了原因:因為10的n次方早就超過了long long的範圍,肯定會炸,所以會想到取模,但是除法這怎麼
取模呢:
(a/b)%mod=a%(b*mod)/b%mod;
這個題目太水了,因為資料太小了,這種方法只要正確取模都能通過,但是原題資料是1e9,那麼這種方法10^n即使取模
,也會爆掉,所以只能用下面的這種方法。
正確求解是:
模擬除法,但是和有區別,原因是此題不需要求出商的每一位是什麼,只需要找出某一位商是什麼,那麼就用到了一種方法:對不需要求出的
位,只需要保留除法之後的餘數就行了,用%b來實現,進行到下一位那麼則需要*10來實現,當實現到要求的某位的前一位的時候,則需要停止,
此時要做的就是實現最後一位,需要*10並且/b。轉化成程式碼,如下:
既然10^n取模會爆掉,那就求n-1次方,最後再乘上10,這樣中間取模就不會爆掉。
#include<stdio.h> #include<string.h> #include<math.h> int b; long long quick(long long a,long long c) { long long ans=1; while(c!=0) { if(c&1) ans=ans*a%b; a=a*a%b; c=c/2; } return ans%b; } int main() { int a,n; while(~scanf("%d%d%d",&a,&b,&n)) { long long len=(a%b*quick(10,n-1))%b; long long ans=10*len/b; printf("%lld\n",ans); } }