题面:
地图
(compress.cpp / stdin / stdout)题目描述
众而周知,8000m×8000m 的地图相当大, 却还是满足不了萌萌哒选手 compress。
compress 说:“我要 xm×ym 的大地图!” 既然你无法满足 compress 的地图梦, 那你就帮他算算他要的地图到底有多大吧!
输入
输入包含两行。
第一行输入一个正整数 x,第二行输入一个正整数 y。
输出
输出包含一行一个整数 s,s=xy。
样例
输入
8000 8000
输出
64000000
数据规模与约定
对于 5% 的数据,xy 在 int 范围内。
对于 10%的数据,xyxy 在 long long 范围内。
对于 20% 的数据,x,yx,y 在 long long 范围内。
对于 50% 的数据,x,y≤105000。
对于 100% 的数据,x,y≤1080000。
这道题若是用普通的高精度乘法可以得到50分,但是对于100%的数据的话一定会超时,所以我们用压位高精度来做,换时间。
所谓压位高精度就相当于把本来算一位的事换成一次算多位,其实一位也就相当于以10进位的算法,而压位也就是10的n次方进制罢了。
具体来说就是用一个数组来保存多位的数,位数越多运算速度就(只是进位过程)快几倍,一开始预处理,进行多位的(题中w)转化数字,存入到数组中,相当于本来是1000000001,九位保存的话就保存为a[1] = 1,a[2] = 1,显而易见快了多少。
既然数组保存为9位,则输出也要九位,所以用到了printf("%0*d,w,a[j])这样的写法,意为输出w位数,不足w位补零。
具体计算过程如下所示:
#include<bits/stdc++.h> 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; }