高精度压位乘法

题面:

地图

(compress.cpp / stdin / stdout)
stdin / stdout
TL: 1 s / ML: 512 MiB

题目描述

众而周知,8000m×8000m       的地图相当大, 却还是满足不了萌萌哒选手 compress。

compress 说:“我要 xm×ym 的大地图!” 既然你无法满足 compress 的地图梦, 那你就帮他算算他要的地图到底有多大吧!

输入

输入包含两行。

第一行输入一个正整数 x,第二行输入一个正整数 y

输出

输出包含一行一个整数 ss=xy

样例

输入

8000
8000

输出

64000000

数据规模与约定

对于 5% 的数据,xy 在 int 范围内。

对于 10%的数据,xyxy 在 long long 范围内。

对于 20% 的数据,x,yx,y 在 long long 范围内。

对于 50% 的数据,x,y105000

对于 100% 的数据,x,y1080000

这道题若是用普通的高精度乘法可以得到50分,但是对于100%的数据的话一定会超时,所以我们用压位高精度来做,换时间。

所谓压位高精度就相当于把本来算一位的事换成一次算多位,其实一位也就相当于以10进位的算法,而压位也就是10的n次方进制罢了。

具体来说就是用一个数组来保存多位的数,位数越多运算速度就(只是进位过程)快几倍,一开始预处理,进行多位的(题中w)转化数字,存入到数组中,相当于本来是1000000001,九位保存的话就保存为a[1] = 1,a[2] = 1,显而易见快了多少。

既然数组保存为9位,则输出也要九位,所以用到了printf("%0*d,w,a[j])这样的写法,意为输出w位数,不足w位补零。

具体计算过程如下所示:

#include
using namespace std;
#define w 9
const long long jw = 1e9;
const int MAXN = 800005;
char s1[MAXN],s2[MAXN];
long long a[MAXN],b[MAXN],ans[MAXN];

int change(char s[],long long n[])
{
	char temp[MAXN];
	int len = strlen(s + 1),now = 0;
	while(len/w)
	{
		strncpy(temp,s+len-w + 1,w);
		n[++now] = atoi(temp);
		len -= w;
	}
	if(len)
	{
		memset(temp,0,sizeof temp); 
		strncpy(temp,s + 1,len);
		n[++now] = atoi(temp);
	}
	return now;
}
void calc(long long a[],long long b[],long long c[],int l1,int l2)
{
	
	for(int i = 1;i <= l1;i++)
	{
		for(int j = 1;j <= l2;j++)
		{
			c[i + j - 1] += a[i] * b[j];
			c[i + j] += c[i + j - 1] / jw;
			c[i + j - 1] = c[i + j - 1] % jw;
		}
	}
	return;
}
void print(long long a[])
{
	for(int i = 200000;i > 0;i--)
	{
		if(a[i] != 0)
		{
			printf("%d",a[i]);
			for(int j = i - 1;j >= 1;j--)
			{
				printf("%0*d",w,a[j]);
			}
			printf("\n");
			break;
		}
	}
}
int main()
{
	scanf("%s%s",s1 + 1,s2 + 1);
	int la = change(s1 ,a),
		lb = change(s2 ,b);
		
	calc(a,b,ans,la,lb);
	
	print(ans);
	return 0;
}

你可能感兴趣的:(高精度压位乘法)