zoukankan      html  css  js  c++  java
  • 两个大数相乘

    HDU 1402

    A * B Problem Plus

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 26545    Accepted Submission(s): 6964


    Problem Description
    Calculate A * B.
     
    Input
    Each line will contain two integers A and B. Process to end of file.

    Note: the length of each integer will not exceed 50000.
     
    Output
    For each case, output A * B in one line.
     
    Sample Input
    1 2 1000 2
     
    Sample Output
    2 2000
     
    思路分析 : 两个 5e4 的多项式相乘,显然最朴素的 n^2 的高精度乘法是过不去的 , 这里可以用 fft , 将两个数看成是多项式即可
        有几个坑点 , 0 * 654651 = 0 , 要把首位前面的 0 全去掉
    代码示例 :
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 1e5+5;
    const int maxm = 5e5+5;
    char s1[maxn], s2[maxn];
    const double pi = acos(-1.0);
    
    struct Complex{
        double x, y;
        Complex (double _x=0, double _y=0):x(_x), y(_y){}
        Complex operator -(const Complex &b)const{
            return Complex(x-b.x, y-b.y);
        }
        Complex operator +(const Complex &b)const{
            return Complex(x+b.x, y+b.y);
        }
        Complex operator *(const Complex &b)const{
            return Complex(x*b.x-y*b.y, x*b.y+y*b.x);
        }
    };
    Complex x1[maxm], x2[maxm];
    void change(Complex y[], int len){
        for(int i = 1, j = len/2; i < len-1; i++){
            if (i < j) swap(y[i], y[j]);
            int k = len/2;
            while(j >= k){
                j -= k;
                k /= 2;
            }
            if (j < k) j += k;
        }
    }
     
    void fft(Complex y[], int len, int on){
        change(y, len);
        for(int h = 2; h <= len; h <<= 1){
            Complex wn(cos(-on*2*pi/h), sin(-on*2*pi/h));
            for(int j = 0; j < len; j += h){
                Complex w(1, 0);
                for(int k = j; k < j+h/2; k++){
                    Complex u = y[k];
                    Complex t = w*y[k+h/2];
                    y[k] = u+t;
                    y[k+h/2] = u-t;
                    w = w*wn;
                }
            }
        }
        if (on == -1){
            for(int i = 0; i < len; i++)
                y[i].x /= len;
        }
    }
    vector<int>ans;
    int sum[maxm];
    
    int main () {
    	
    	while(~scanf("%s%s", s1, s2)){
    		int l1 = strlen(s1);
    		int l2 = strlen(s2);
    		memset(x1, 0, sizeof(x1));
    		memset(x2, 0, sizeof(x2));
    		int len = 1;
    		while(len < (l1+l2-1)) len <<= 1;
    		
    		for(int i = 0; i < l1; i++) x1[i] = Complex((double)(s1[i]-'0'), 0);
    		for(int i = l1; i < len; i++) x1[i] = Complex(0, 0); 
    		for(int i = 0; i < l2; i++) x2[i] = Complex((double)(s2[i]-'0'), 0);
    		for(int i = l2; i < len; i++) x2[i] = Complex(0, 0);
    		fft(x1, len, 1); fft(x2, len, 1);
    		for(int i = 0; i < len; i++) x1[i] = x1[i]*x2[i];
    		fft(x1, len, -1);
    		
    		ans.clear();
    		ans.resize(l1+l2-1);
    		for(int i = l1+l2-2; i >= 0; i--){
    			ans[i] += (int)(x1[i].x+0.5);
    			if (i != 0) {
    				ans[i-1] += ans[i]/10;
    				ans[i] %= 10;	
    			} 
    			else {
    				int temp = ans[0]/10;
    				if(temp != 0){
    					ans[0] %= 10;
    					ans.insert(ans.begin(), temp);
    				}
    			}
    		}		
    		int pos = 0;
    		for(int i = 0; i < l1+l2-1; i++) {
    			pos = i;
    			if (ans[i] != 0) break;
    		}
    		for(int i = pos; i < ans.size(); i++){
    			printf("%d", ans[i]);
    		}
    		printf("
    ");	
    		memset(s1, '', sizeof(s1));
    		memset(s2, '', sizeof(s2));	
    	}	
    	
    	
    	return 0;
    }
    /*
    4121 46
    1321 46
    */
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    解决在cmd命令下不能输入中文方法
    报错注入
    html表单中的name属性和value属性
    xss漏洞
    DVWA-xss反射型(跨站脚本漏洞)
    DVWA-brute force
    owsap top 10 2017(十大web安全应用程序安全)
    sqli_labs less-5
    盲注
    c++ 类
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9516226.html
Copyright © 2011-2022 走看看