1. 程式人生 > >HDU 1402 A * B Problem Plus ——(大數乘法,FFT)

HDU 1402 A * B Problem Plus ——(大數乘法,FFT)

兩個 ret 處理 complex truct std spa strlen mes

  因為剛學fft,想拿這題練練手,結果WA了個爽= =。

  總結幾點犯的錯誤:

  1.要註意處理前導零的問題。

  2.一定要註意數組大小的問題。(前一個fft的題因為沒用到b數組,所以b就沒管,這裏使用了b數組,結果忘記給其大小乘以4倍了)

  代碼如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const double pi = atan(1.0)*4;
 4 const int N = 5e4 + 5;
 5 typedef long long ll;
 6 
 7 struct Complex {
 8
double x,y; 9 Complex(double _x=0,double _y=0) 10 :x(_x),y(_y) {} 11 Complex operator + (Complex &tt) { return Complex(x+tt.x,y+tt.y); } 12 Complex operator - (Complex &tt) { return Complex(x-tt.x,y-tt.y); } 13 Complex operator * (Complex &tt) { return Complex(x*tt.x-y*tt.y,x*tt.y+y*tt.x); }
14 }; 15 Complex a[N*4],b[N*4]; 16 void fft(Complex *a, int n, int rev) { 17 // n是(大於等於相乘的兩個數組長度)2的冪次 ; 比如長度是5 ,那麽 n = 8 2^2 < 5 2^3 > 5 18 // 從0開始表示長度,對a進行操作 19 // rev==1進行DFT,==-1進行IDFT 20 for (int i = 1,j = 0; i < n; ++ i) { 21 for (int k = n>>1; k > (j^=k); k >>= 1
); 22 if (i<j) std::swap(a[i],a[j]); 23 } 24 for (int m = 2; m <= n; m <<= 1) { 25 Complex wm(cos(2*pi*rev/m),sin(2*pi*rev/m)); 26 for (int i = 0; i < n; i += m) { 27 Complex w(1.0,0.0); 28 for (int j = i; j < i+m/2; ++ j) { 29 Complex t = w*a[j+m/2]; 30 a[j+m/2] = a[j] - t; 31 a[j] = a[j] + t; 32 w = w * wm; 33 } 34 } 35 } 36 if (rev==-1) { 37 for (int i = 0; i < n; ++ i) a[i].x /= n,a[i].y /= n; 38 } 39 } 40 41 char s[N], t[N]; 42 int c[N*2]; 43 44 int main(){ 45 /*a[0] = Complex(0,0); // a[0]: x的0次項。 46 a[1] = Complex(1,0); 47 a[2] = Complex(2,0); 48 a[3] = Complex(3,0); 49 50 b[0] = Complex(3,0); 51 b[1] = Complex(2,0); 52 b[2] = Complex(1,0); 53 b[3] = Complex(0,0); 54 fft(a,8,1); 55 fft(b,8,1); 56 for(int i = 0 ; i < 8 ; i ++){ 57 a[i] = a[i] * b[i]; 58 } 59 fft(a,8,-1); 60 for(int i = 0 ; i < 8 ; i ++){ 61 cout << i << " " << a[i].x << endl;; 62 }*/ 63 while(scanf("%s%s",s,t) == 2) 64 { 65 int n = strlen(s), m = strlen(t); 66 for(int i=0;i<n;i++) a[i] = Complex(s[n-i-1]-0, 0); 67 for(int i=0;i<m;i++) b[i] = Complex(t[m-i-1]-0, 0); 68 int len = n+m-1; 69 int LIM = 1; 70 while(LIM < len) LIM <<= 1; 71 for(int i=n;i<LIM;i++) a[i] = Complex(0, 0); 72 for(int i=m;i<LIM;i++) b[i] = Complex(0, 0); 73 fft(a, LIM, 1); 74 fft(b, LIM, 1); 75 for(int i=0;i<LIM;i++) a[i] = a[i] * b[i]; 76 fft(a, LIM, -1); 77 memset(c, 0, sizeof c); 78 for(int i=0;i<len-1;i++) 79 { 80 c[i] += (int)(a[i].x + 0.1); 81 c[i+1] += c[i] / 10; 82 c[i] %= 10; 83 } 84 c[len-1] += (int)(a[len-1].x + 0.1); 85 if(c[len-1] > 9) 86 { 87 c[len] = c[len-1] / 10; 88 c[len-1] %= 10; 89 len++; 90 } 91 for(int i=len-1;i>0;i--) if(c[i] == 0) len--; else break; // 0 * 345 = 0 instead of 000 92 for(int i=0;i<len/2;i++) swap(c[i], c[len-i-1]); 93 for(int i=0;i<len;i++) printf("%d",c[i]); 94 puts(""); 95 } 96 return 0; 97 }

HDU 1402 A * B Problem Plus ——(大數乘法,FFT)