標籤:
題目描述 Description除法是計算中的基礎運算,雖然規則簡單,但是位元太多了,也難免會出錯。現在的問題是:給定任意位元(足夠大就可以啦O(∩_∩)O)的一個被除數,再給定一個long long類型的除數,求它的餘數,並保留小數點後s位。
輸入輸出格式 Input/output
輸入格式:
三行:第一行:被除數第二行:除數第三行:一個數s,表示保留小數點後s位
輸出格式:
一行數,表示計算的結果(不可以有前置0)
輸入輸出範例 Sample input/output
範例測試點#1
輸入範例:123456789
123
30
輸入範例:
1003713.731707317073170731707317073170
思路:這題的資料量很大,大資料類型的,如果直接計算是不可取的,必須用高精度演算法。
這裡可以分為幾個函數來計算:
①高精度除以單精確度法函數:專題裡面會細細地講的
②倒序輸出函數:專題裡面會細細地講的
③手算類比了一下除法的過程,餘數*10再除以除數,就得了第一位小數點後的數,儲存到k裡面,輸出再把餘數賦值為餘數-除數*K(想不通的,可以手動類比一下過程,其實很簡單的)然後一位一位輸出即可
代碼如下:
1 #include <stdio.h> 2 #include <string.h> 3 #define MaxLength 99999 4 int x,q;//q是備份餘數用的 5 void output(int c[])//倒序輸出函數 6 { 7 int i; 8 for(i=c[0];i>=1;i--) 9 printf("%d",c[i]);10 }11 /*============================================================================*/12 void div(char strA[],int b,int c[])//高精度數a除以整數b,結果儲存在c。13 {14 int a[MaxLength],i,lena,lenc,j,t;15 memset(a,0,sizeof(a));16 memset(c,0,sizeof(c));17 if(b==0) 18 {19 c[0]=1;20 c[1]=0;21 return ;22 }23 lena=strlen(strA);24 for(i=0;i<lena;i++) //把串strA正序儲存到數組a 25 a[i+1]=strA[i]-‘0‘; 26 x=0;27 for(i=1;i<=lena;i++) //按位相除 28 {29 c[i]=(x*10+a[i])/b;30 x=(x*10+a[i])%b; 31 } 32 lenc=1;33 while(c[lenc]==0&&lenc<lena) //高位可能會有一些無意義的0,需要把lenc定好位 34 lenc++; 35 c[0]=lena-lenc+1;36 for(j=1;j<=c[0];j++) //把數組c整體左移,也就是把首碼0給覆蓋掉 37 {38 c[j]=c[lenc];39 lenc++;40 }41 for(i=1,j=c[0];i<j;i++,j--)42 {43 t=c[i];c[i]=c[j];c[j]=t;44 }45 q=x;//備份一下餘數 46 output(c);//傳入輸出函數47 }48 /*============================================================================*/49 int main()50 {51 char a[MaxLength];52 int b[MaxLength];53 int i,k;54 long long s,n;55 gets(a);56 scanf("%I64d",&n);57 scanf("%d",&s);58 div(a,n,b);59 printf("."); 60 for(i=0;i<s;i++)//小數點後s位 61 {62 x=x*10;63 k=x/n;64 printf("%d",k);65 x=x-n*k; 66 }67 printf("\n%d\n",q); 68 return 0;69 }
大資料除法(Large data division)