hdu1402

大数乘法

自己的代码tle,快速傅里叶变换没弄懂:

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
__int64 sum1[13550],sum2[13550];
__int64 sum[13550];
void fun(char *str1,char *str2)
{
    int num1=0,len=strlen(str1),num2=0;;
    for(char *p=str1+len-6;p>str1;*p='\0',p-=6)
      sum1[num1++]=atoi(p);
    sum1[num1]=atoi(str1);
    len=strlen(str2);
    for(char *p=str2+len-6;p>str2;*p='\0',p-=6)
      sum2[num2++]=atoi(p);
    sum2[num2]=atoi(str2);
    int i,j,num;
    memset(sum,0,sizeof(sum));
    for(i=0;i<=num1;i++)
       for(j=0,num=i;j<=num2;j++)
       {
           sum[num]+=sum1[i]*sum2[j];
           sum[num+1]+=sum[num]/1000000;
           sum[num]%=1000000;
           num++;
       }
    while(sum[num]==0) num--;
    if(num<0) {printf("0\n");return ;}
    printf("%I64d",sum[num--]);
    for(;num>=0;num--)
      printf("%06I64d",sum[num]);
    printf("\n");
}
int main()
{
    char str1[50050],str2[50050];
    while(~scanf("%s",str1))
    {
        scanf(" %s",str2);
        if(str2[0]=='0'||str1[0]=='0') {printf("0\n");continue;}
        fun(str1,str2);
    }
    return 0;
}
下面代码贴别人的
 
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const double PI= acos(-1.0);
struct vir
{
    double re,im; //实部和虚部
    vir(double a=0,double b=0){
        re=a; im=b;
    }
    vir operator +(const vir &b){
        return vir(re+b.re,im+b.im);
    }
    vir operator -(const vir &b){
        return vir(re-b.re, im-b.im);
    }
    vir operator *(const vir &b){
        return vir(re*b.re-im*b.im , re*b.im+im*b.re);
    }
};
vir x1[200005],x2[200005];
void change(vir *x,int len,int loglen)
{
    int i,j,k,t;
    for(i=0;i<len;i++)
    {
        t=i;
        for(j=k=0; j<loglen; j++,t>>=1)
            k= (k<<1)|(t&1);
        if(k<i){
            vir wt=x[k];
            x[k]=x[i];
            x[i]=wt;
        }
    }
}
void fft(vir *x,int len,int loglen)
{
    int i,j,t,s,e;
    change(x,len,loglen);
    t=1;
    for(i=0;i<loglen;i++,t<<=1)
    {
        s=0;  e=s+t;
        while(s<len)
        {
            vir a,b,wo(cos(PI/t),sin(PI/t)),wn(1,0);
            for(j=s;j<s+t;j++)
            {
                a=x[j];  b=x[j+t]*wn;
                x[j]=a+b; x[j+t]=a-b;
                wn=wn*wo;
            }
            s=e+t;  e=s+t;
        }
    }
}
void dit_fft(vir *x,int len,int loglen)
{
    int i,j,s,e,t=1<<loglen;
    for(i=0;i<loglen;i++)
    {
        t>>=1;
        s=0; e=s+t;
        while(s<len)
        {
            vir a,b,wn(1,0),wo(cos(PI/t),-sin(PI/t));
            for(j=s;j<s+t;j++)
            {
                a=x[j]+x[j+t]; b=(x[j]-x[j+t])*wn;
                x[j]=a;  x[j+t]=b;
                wn=wn*wo;
            }
            s=e+t;  e=s+t;
        }
    }
    change(x,len,loglen);
    for(i=0;i<len;i++)
        x[i].re/=len;
}
int main()
{
    char a[100005],b[100005];
    int i,len1,len2,len,loglen;
    int t,over;
    while(scanf("%s%s",a,b)!=EOF)
    {
        len1=strlen(a)<<1;
        len2=strlen(b)<<1;
        len=1;
        loglen=0;
        while(len<len1)
            len<<=1, loglen++;
        while(len<len2)
            len<<=1, loglen++;
        //init
        for(i=0;a[i];i++)
            x1[i].re=a[i]-'0', x1[i].im=0;
        for(;i<len;i++)
            x1[i].re=x1[i].im=0;
        for(i=0;b[i];i++)
            x2[i].re=b[i]-'0', x2[i].im=0;
        for(;i<len;i++)
            x2[i].re=x2[i].im=0;
        fft(x1,len,loglen);
        fft(x2,len,loglen);
        for(i=0;i<len;i++)
            x1[i] = x1[i]*x2[i];
        dit_fft(x1,len,loglen);
        //将x1.re从浮点数转化为十进制整型存入a
        for(i=(len1+len2)/2-2,over=len=0;i>=0;i--)
        {
            t=x1[i].re+over+0.5;
            a[len++]= t%10;
            over = t/10;
        }
        while(over){
            a[len++]=over%10;
            over/=10;
        }
        for(len--;len>=0&&!a[len];len--);
        if(len<0)
            putchar('0');
        else
            for(;len>=0;len--)
                putchar(a[len]+'0');
        putchar('\n');
    }
    return 0;
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值