bzoj1876: [SDOI2009]SuperGCD
更相减损数。
上手就debug了3个小时,直接给我看哭了。
3个函数都写错了是什么感受?
乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数。
除2函数要从后往前除,这样前面的数借来的位不会除2次。
然后函数里面俩个类里面的变量名不要打混。
哭瞎
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxl = 2000 + 10; const int d[]={10000000,1,10,100,1000,10000,100000,1000000}; char s[20010]; int cnt; struct bigint { int a[maxl],len; int& operator [] (int x) { return a[x]; } void init(char s[]) { int n=strlen(s+1); len=(n+7)/8; for(int i=1,t,e;i<=n;i++) { e=i%8; t=(i+7)/8; a[t]+=(s[n-i+1]-'0')*d[e]; } } void print() { printf("%d",a[len]); for(int i=len-1;i>=1;i--) printf("%08d",a[i]); printf("\n"); } void div() { for(int i=1;i<=len;i++) { if(a[i]&1) a[i-1]+=50000000; a[i]/=2; } if(a[len]==0) len--; a[0]=0; } void mul() { for(int i=len;i>0;i--) { a[i]<<=1; a[i+1]+=a[i]/100000000; a[i]%=100000000; } while(a[len+1]) len++; } bigint operator - (bigint b) { bigint c; for(int i=1;i<=len;i++) { c[i]+=a[i]-b[i]; if(c[i]<0) {c[i]+=100000000; c[i+1]--;} } c.len=len; while(!c[c.len] && c.len) c.len--; return c; } bool operator < (bigint b) { if(len != b.len) { if(len > b.len ) return 0; else return 1; } for(int i=len;i>=1;i--) { if(a[i] != b[i]) { if(a[i]<b[i]) return 1; else return 0; } } return 0; } bigint() { memset(a,0,sizeof(a)); len=0; } }a,b; int main() { scanf("%s",s+1); a.init(s); scanf("%s",s+1); b.init(s); cnt=0; while(1) { while(!(a[1]&1) && !(b[1]&1)) {cnt++; a.div(); b.div();} while(!(a[1]&1)) a.div(); while(!(b[1]&1)) b.div(); if(b<a) a=a-b; else { b=b-a; if(b.len==0) { while(cnt--) a.mul(); a.print(); break; } } } return 0; }