HDU-1753 大明A+B【大數相加】
阿新 • • 發佈:2019-02-06
解題思路:
大數相加問題,但是有三種情況:2個整數,1個整數1個小數,2個小數。
這就需要我們單獨處理每種情況,而且這道題需要保證沒有多餘的前導0和後導0,剛開始想到簡單了。結果到最後搞了150行才過。悲劇。
這道題的巧妙做法是:把每種情況都轉換成2個小數來搞,這樣就只有1種情況了。
程式碼如下:
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int N = 810; char a[N], b[N]; int c[N], d[N]; int main() { int flag1, flag2, len1, len2, pos; int up, top, down; while(scanf("%s %s", a, b) != EOF) { flag1 = flag2 = -1; memset(c, 0, sizeof(c)); memset(d, 0, sizeof(d)); len1 = strlen(a); len2 = strlen(b); for(int i = 0; i < len1; ++i) //整數部分、小數部分 if(a[i] == '.') flag1 = i; for(int i = 0; i < len2; ++i) //整數部分、小數部分 if(b[i] == '.') flag2 = i; if(flag1 == - 1 && flag2 == -1) //2整 { for(int i = len1 - 1, k = 0; i >= 0; --i) c[k++] = a[i] - '0'; for(int i = len2 - 1, k = 0; i >= 0; --i) d[k++] = b[i] - '0'; for(int i = 0, up = 0; i < N; ++i) { c[i] = c[i] + d[i] + up; up = c[i] / 10; c[i] %= 10; } for(top = N -1; !c[top] && top >= 0; --top); if(top < 0) { printf("0\n"); continue; } for(int i = top; i >= 0; --i) printf("%d", c[i]); printf("\n"); } else if(flag1 != -1 && flag2 != -1) //2小 { if(len1 - 1 - flag1 > len2 - 1 - flag2) //a小數部分長 { for(int i = 0; i < len1 - len2 + flag2 - flag1; ++i) b[len2 + i] = '0'; b[len1 + flag2 - flag1 + 1] = '\0'; len2 += len1 - len2 + flag2 - flag1; } else if((len1 - 1 - flag1 < len2 - 1 - flag2)) { for(int i = 0; i < len2 - len1 + flag1 - flag2; ++i) a[len1 + i] = '0'; a[len2 + flag1 - flag2 + 1] = '\0'; len1 += len2 - len1 + flag1 - flag2; } pos = 0; for(int i = len1 - 1; i >= 0; --i) if(a[i] != '.') pos++; else break; for(int i = len1 - 1, k = 0; i >= 0; --i) if(a[i] != '.') c[k++] = a[i] - '0'; for(int i = len2 - 1, k = 0; i >= 0; --i) if(b[i] != '.') d[k++] = b[i] - '0'; for(int i = 0, up = 0; i < N; ++i) { c[i] = c[i] + d[i] + up; up = c[i] / 10; c[i] = c[i] % 10; } for(int i = 0; i < N; ++i) a[i] = c[i] + '0'; for(top = N - 1; a[top] == '0'; --top); //去前導0 if(top < 0) { printf("0\n"); continue; } for(down = 0; a[down] == '0' && down < pos; ++down); //去後導0 for(int i = top; i >= down; --i) if(i == pos && down != pos) printf("%c.", a[i]); else printf("%c", a[i]); printf("\n"); } else //1整、1小 { if(flag1 == -1) //b小 { for(int i = len1 - 1, k = 0; i >= 0; --i) c[k++] = a[i] - '0'; for(int i = flag2 - 1, k = 0; i >= 0; --i) d[k++] = b[i] - '0'; for(int i = 0, up = 0; i < N; ++i) { c[i] = c[i] + d[i] + up; up = c[i] / 10; c[i] %= 10; } for(top = N - 1; !c[top]; --top); //去前導0 if(top < 0) { printf("0\n"); continue; } for(down = len2 - 1; b[down] == '0'; --down); //去後導0 for(int i = top; i >= 0; --i) printf("%d", c[i]); if(b[down] != '.') for(int i = flag2; i <= down; ++i) printf("%c", b[i]); printf("\n"); } else //a小 { for(int i = flag1 - 1, k = 0; i >= 0; --i) c[k++] = a[i] - '0'; for(int i = len2 - 1, k = 0; i >= 0; --i) d[k++] = b[i] - '0'; for(int i = 0, up = 0; i < N; ++i) { c[i] = c[i] + d[i] + up; up = c[i] / 10; c[i] %= 10; } for(top = N - 1; !c[top]; --top); //去前導0 if(top < 0) { printf("0\n"); continue; } for(down = len1 - 1; a[down] == '0'; --down); //去後導0 for(int i = top; i >= 0; --i) printf("%d", c[i]); if(a[down] != '.') for(int i = flag1; i <= down; ++i) printf("%c", a[i]); printf("\n"); } } } return 0; }
JAVA則超級輕鬆水過啊!!!!!!!!150行和20行,鬱悶啊。。。。
JAVA,你太強悍了。ORZ
程式碼如下:
import java.math.BigDecimal; import java.util.*; public class Main { public static void main(String[] args) { BigDecimal a, b, c; Scanner cin = new Scanner(System.in); while(cin.hasNext()) { a = cin.nextBigDecimal(); b = cin.nextBigDecimal(); c = a.add(b); if(c.compareTo(BigDecimal.ZERO) == 0) System.out.println("0"); else System.out.println(c.stripTrailingZeros().toPlainString()); } } }