大一的時候,只要寫OJ遇到大數,我都是直接用python,因為python支援大數運算,所以所有的大數題目就會變得簡單很多。而我也有用C寫過,加法是最簡單的,減法難了一點點、乘法難了一些但還應付得來,不過除法我就完全束手無策,光是看完做法並轉成code就花了大概八小時。
解題想法:
1.將輸入的x,y字串轉成數字並順序顛倒地存入a,b陣列。
2.加法:一個位數加完就cl++(cl代表數字c有幾位數),進位的時候如果是最大的位數進,cl再+1。
3.減法:先用xBigger函式看ab大小,0表a<b,就讓c=b-a,並在最前面輸出負號;1表y>x,就讓c=b-a,然後直接輸出;2表x=y,直接輸出0。
4.乘法:先乘完所有位數,再一一進位。
5.除法:一樣先用xBigger函式看ab大小,若xBigger()=0就直接輸出0,>0的話就先讓b的位數對齊a,意思就是:
a = 123456
b = 789
在b的最後面加0補齊,讓b的位數等於a的位數。
a = 123456
b = 789000
對齊之後,再來就是除法的部分了,不過我們是用減法來完成。舉7/2為例,直接除可以得到3餘1,用減的話就是7去減2減3次得到1,所以==減的次數就是商==。
那要減多少次呢?就是減到==被除數小於除數為止==,每個位數的商都是用這樣的方式求出,先從最大的位數開始,減到不能減之後就==把除數的最後一個0拿掉==,然後求下一個位數的商,以此類推,做到除數沒有0之後就退出並印出商的值。
這裡我們令a=123456,b=789
a = 123 456
b = 789 000
c = 000 000
b>a,所以商為0,b/=10。
a = 1234 56
b = 0789 00
c = 0000 00
可減1次,所以商為1,b/=10。
a = 04455 6
b = 00789 0
c = 00010 0
可減5次,所以商為5,b/=10。
a = 005106
b = 000789
c = 000150
可減5次,所以商為5,然後b借的0都拿掉了,所以退出並輸出155。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| #include<stdio.h> #include<stdint.h> #include<string.h> #define max(x,y) x>y?x:y
int16_t a[505],b[505],c[505],d[505],xBig;
int xBigger(int16_t a[],int16_t b[],int al,int bl){ if(al>bl){return 1;} else if(al==bl){ for(int i=al-1;i>=0;i--){ if(a[i]<b[i]){return 0;} else if(a[i]>b[i]){return 1;} } return 2; } return 0; }
void sub(int16_t a[],int16_t d[],int al,int dl){ int i; for(i=0;i<dl;i++){a[i]-=d[i];} for(i=0;i<al;i++){ if(a[i]<0){a[i]+=10;a[i+1]--;} } }
int main(){ char x[505],y[505],op; scanf("%s %c %s",x,&op,y); int i,j,cl=0,jin=0; int al=strlen(x),bl=strlen(y); for(i=0;i<505;i++){a[i]=0;b[i]=0;c[i]=0;} for(i=0;i<al;i++){a[al-1-i]=x[i]-48;} for(i=0;i<bl;i++){b[bl-1-i]=y[i]-48;} switch(op){ case '+': for(i=0;i<al||i<bl;i++){ c[i]+=a[i]+b[i]; if(c[i]>=10){ c[i+1]+=c[i]/10; c[i]=c[i]%10; if(i==max(x,y)-1){cl++;} } cl++; } break; case '-': if(xBigger(a,b,al,bl)!=2){ if(xBigger(a,b,al,bl)==1){ for(i=0;i<al;i++){c[i]=a[i]-b[i];cl++;} } else if(xBigger(a,b,al,bl)==0){ printf("-"); for(i=0;i<bl;i++){c[i]=b[i]-a[i];cl++;} } for(i=0;i<cl;i++){ if(c[i]<0){c[i]+=10;c[i+1]--;} } if(c[cl-1]==0){cl--;} } else{cl=1;} break; case '*': if( (al==1&&a[0]==0) || (bl==1&&b[0]==0) ){cl=1;} else{ for(i=0;i<bl;i++){ for(j=0;j<al;j++){c[i+j]+=a[j]*b[i];} } for(i=0;i<al+bl;i++){ if(c[i]>=10){c[i+1]+=c[i]/10;c[i]=c[i]%10;} cl++; } if(c[al+bl-1]==0){cl--;} } break; case '/': if( (al==1&&a[0]==0) || (bl==1&&b[0]==0) ){cl=1;} else{ if(xBigger(a,b,al,bl)>0){ int dl=al-bl;cl=dl+1; for(i=dl;i>=0;i--){ for(j=bl-1;j>=0;j--){d[j+i]=b[j];} for(j=0;j<i;j++){d[j]=0;} while(xBigger(a,d,al,bl+i)>0){ sub(a,d,al,bl+i); if(a[al-1]==0){al--;} c[i]++; } for(j=0;j<al;j++){d[j]=0;} } if(c[cl-1]==0){cl--;} } else{cl=1;} } break; } for(i=cl-1;i>=0;i--){printf("%hd",c[i]);} printf("\n"); return 0; }
|
說了這麼多,這個code在我自己的終端機試了很多測資都能正確執行,但我還是NA了兩次 ,兩次都是8筆測資對7筆,而且兩次錯的小測資都一模一樣,逼得我只好開大絕用python,敲短短地6行就AC。
1 2 3 4 5 6
| a,op,b=input().split() x,y=int(a),int(b) if(op=='+'):print(x+y) elif(op=='-'):print(x-y) elif(op=='*'):print(x*y) elif(op=='/'):print(x//y)
|
封面圖源:Pixiv