信息学奥赛一本通 1308:【例1.5】高精除
生活随笔
收集整理的這篇文章主要介紹了
信息学奥赛一本通 1308:【例1.5】高精除
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題目鏈接】
ybt 1308:【例1.5】高精除
【題目考點】
1. 高精度
考察:高精除以高精
高精度計算講解
【題解代碼】
解法1:使用數組與函數
#include<bits/stdc++.h> using namespace std; #define N 305 //從數字數組a的第i位開始,刪除高位的0 void setLen(int a[], int i) {while(a[i] == 0 && i > 1)//去除多余的0i--;a[0] = i; } //將字符數組轉化為數字數組 數字數組從第1位置到第len位置,從低位到高位保存各位數字,第0位置保存數字位數 void toNum(char s[], int a[]) {a[0] = strlen(s);for(int i = 1; i <= a[0]; ++i)a[i] = s[a[0] - i] - '0'; } //輸出數字數組 void showNum(int a[]) {for(int i = a[0]; i >= 1; --i)cout << a[i];cout << endl; } //將數字數組b復制到數字數組a之中 void numcpy(int a[], int b[]) {for(int i = 0; i <= b[0]; ++i)a[i] = b[i]; } //比較兩個數字數組 如果a比b大,返回1,如果a比b小,返回-1,如果二者相等,返回0 int numcmp(int a[], int b[]) {if(a[0] > b[0])//如果a的位數比較多return 1;else if (a[0] < b[0])//如果b的位數比較多return -1;else{for(int i = a[0]; i >= 1; --i){if(a[i] > b[i])return 1;else if(a[i] < b[i])return -1;}return 0;} } //高精減高精 前提:a比b大 void Minus(int a[], int b[], int r[]) {int i;for(i = 1; i <= a[0] || i <= b[0]; ++i){if(a[i] < b[i]){a[i+1]--;a[i] += 10;}r[i] = a[i] - b[i];}setLen(r, i); } //高精度除以高精度 //a = a*10+num,即在數字數組的個位添加一位數,0 <= num <= 9,如2添加1后變為21 void addNum(int a[], int num) {if(a[0] == 1 && a[1] == 0)//如果a是0,那么就把個位設為num a[1] = num;else{for(int i = a[0]; i >= 1; --i)//數組移位a[i+1] = a[i];a[1] = num;a[0]++;} } //高精度除法中的減法代替除法操作,實際就是除法的另一種實現方式 //已知商一定是0~9的數字。a是被除數 b是除數 返回值為商,計算后數組a保存的是余數 int divideByMinus(int a[], int b[]) {int q = 0, r[N];//q:商(減的次數) r:臨時結果 while(numcmp(a, b) >= 0){memset(r, 0, sizeof(r));Minus(a, b, r);numcpy(a, r);//將a設為上次減法的結果q++;}return q; } //高精度數字除以高精度數字 void Divide(int a[], int b[], int r[], int x[])//r:商 x:余數 {for(int i = a[0]; i >= 1; --i){addNum(x, a[i]);r[i] = divideByMinus(x, b);}setLen(r, a[0]); } int main() {int a[N] = {}, b[N] = {}, r[N] = {}, m[N] = {};//必須都初始化為0 r:商 m:余數 char s[N];cin >> s;toNum(s, a);cin >> s;toNum(s, b);Divide(a, b, r, m);showNum(r);showNum(m);return 0; }解法2:使用高精度數字類
#include <bits/stdc++.h> using namespace std; #define N 305 struct HPN {int a[N];//數字數組HPN(){memset(a, 0, sizeof(a));}HPN(char s[]){memset(a, 0, sizeof(a));a[0] = strlen(s);for(int i = 1; i <= a[0]; ++i)a[i] = s[a[0] - i] - '0';}void show(){for(int i = a[0]; i >= 1; --i)cout << a[i];cout << endl;}int& operator [] (int i)//類似數組取值{return a[i];}int numcmp(int a[], int b[]){if(a[0] > b[0])//如果a的位數比較多return 1;else if (a[0] < b[0])//如果b的位數比較多return -1;else{for(int i = a[0]; i >= 1; --i){if(a[i] > b[i])return 1;else if(a[i] < b[i])return -1;}return 0;}}bool operator >= (HPN b){return numcmp(a, b.a) >= 0;}void setLen(int i)//從第i位置開始,向低位尋找,直到找到一個不為0的數位,更新數字長度{while(a[i] == 0 && i > 1)i--;a[0] = i;}void operator -= (HPN b){int i;for(i = 1; i <= a[0] || i <= b[0]; ++i){if(a[i] < b[i]){a[i + 1]--;a[i] += 10;}a[i] -= b[i];}setLen(i);}void addNum(int num)//a = a * 10 + num{if(a[0] == 1 && a[1] == 0)//如果a是0,那么就把個位設為num a[1] = num;else{for(int i = a[0]; i >= 1; --i)//數組移位a[i+1] = a[i];a[1] = num;a[0]++;}}HPN operator / (HPN b) //高精除高精{HPN r, x;//r:商 x:余數 int i;for(i = a[0]; i >= 1; --i){//以下幾句完成x = x * 10 + a[i]x.addNum(a[i]);//求r[i] = x / b; 以減法代替除法int q = 0;//記錄減了幾次,該值就是通過減法代替除法得到的商while(x >= b)//高精度數字比較{x -= b;//高精度數字減法q++;}r[i] = q;}r.setLen(a[0]);return r;}HPN operator % (HPN b) //高精模高精{HPN x;for(int i = a[0]; i >= 1; --i){ //以下幾句完成x = x * 10 + a[i]x.addNum(a[i]);while(x >= b)//高精度數字比較x -= b;//高精度數字減法}return x;} }; int main() {char s1[N], s2[N];cin >> s1;cin >> s2;HPN n1(s1), n2(s2), n3, n4;n3 = n1 / n2;n3.show();n4 = n1 % n2;n4.show();return 0; }總結
以上是生活随笔為你收集整理的信息学奥赛一本通 1308:【例1.5】高精除的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中random方法取值范围_Ja
- 下一篇: java 判断 框架类型_第10章-验证