標籤:演算法 acm c 原始碼 uva
註明:
本題使用了兩種解法,第一種參考了網上一種非常普遍的解法,即使用atof函數將兩個數字字串轉化為兩個浮點數,然後直接和int的最大值比較即可。這種方法較簡單,不過也是在資料較小的情況下行得通。而第二種是我自己寫的一種更較為普遍的解法,其實也就是直接根據字串進行高精度的運算而已。自己用了很多資料進行測試都沒有錯,可是就是AC不了,不知道為什麼。希望大神指教!!!
題目:
Overflow
Write a program that reads an expression consisting of two non-negative integer and an operator. Determine if either integer or the result of the expression is too large to be represented as a ``normal‘‘ signed integer (typeinteger if you are working Pascal, type int if you are working in C).
Input
An unspecified number of lines. Each line will contain an integer, one of the two operators+ or *, and another integer.
Output
For each line of input, print the input followed by 0-3 lines containing as many of these three messages as are appropriate: ``first number too big‘‘, ``second number too big‘‘, ``result too big‘‘.
Sample Input
300 + 39999999999999999999999 + 11
Sample Output
300 + 39999999999999999999999 + 11first number too bigresult too big
原始碼:(解法一)
#include <stdio.h>#include <stdlib.h>#define INT 2147483647int main(){ double a,b; char x[500],y[500]; char operator; while(scanf("%s %c %s",x,operator,y)==3){ a=atof(x); b=atof(y); if(a>INT) printf("first number too big\n"); if(b>INT) printf("second number too big\n"); if(operator=='+'&&a+b>INT||operator=='*'&&a*b>INT) printf("result too big\n"); } return 0;}
(解法二)
#include <stdio.h>#include <string.h>#define MAXN 1000+5char x[MAXN],y[MAXN];char operator;char ans[MAXN];//儲存答案的字串,未必從開頭開始char Int[]="2147483647";char *p;//指向ans中,答案字串開始的位置int int_cmp(char *);//比較輸入字串和Int的大小,大於返回1,否則返回0void add();void multip();int main(){ //freopen("data","r",stdin); while(scanf("%s %c %s",x,&operator,y)==3){ printf("%s %c %s\n",x,operator,y); if(int_cmp(x)) printf("first number too big\n"); if(int_cmp(y)) printf("second number too big\n"); if(operator=='+') add(); else if(operator=='*') multip(); if(int_cmp(p)) printf("result too big\n"); } return 0;}int int_cmp(char *s){ int len1=strlen(Int); int len2=strlen(s); int i; if(len2>len1) return 1; else if(len1>len2) return 0; else { for(i=0;i<len1;i++) if(Int[i]<s[i]) return 1; else if(Int[i]>s[i]) return 0; return 0; }}void add(){//兩個字串的加法 int j=MAXN-1; int carry,sum; int len1=strlen(x),len2=strlen(y); int i,max; max=len1>len2?len1:len2; ans[j--]='\0'; carry=0; for(i=0;i<max;i++){//從兩串的末尾開始相加,結果從ans的末尾開始放入 sum=carry; if(len1-i>0) sum+=x[len1-i-1]-'0'; if(len2-i>0) sum+=y[len2-i-1]-'0'; ans[j--]=sum%10+'0'; carry=sum/10; } while(carry){//將剩餘的進位依次放好 ans[j--]=carry%10+'0'; carry/=10; } p=ans+j+1; while(*p=='0') p++; if(*p=='\0') p--; return ;}void multip(){ int i,j,left,k,pos,product,carry; int x_len,y_len; ans[MAXN-1]='\0'; k=left=MAXN-1; x_len=strlen(x); y_len=strlen(y); for(i=0;i<MAXN-1;i++) ans[i]='0'; for(i=y_len-1;i>=0;i--){ k--;//標記每個乘數最右的位置 pos=k; carry=0; for(j=x_len-1;j>=0;j--){ product=(y[i]-'0')*(x[j]-'0')+ans[pos]-'0'+carry; ans[pos]=product%10+'0'; pos--; carry=product/10; } while(carry){ carry+=ans[pos]-'0'; ans[pos]=carry%10+'0'; pos--; carry/=10; } left=left<=pos+1?left:pos+1; } p=ans+left; while(*p=='0')//若答案串的前面有0,則去掉 p++; if(*p=='\0') p--; return;}