题目链接:
解题报告:问一个“M”型可以把一个矩形的平面最多分割成多少块。
输入是有n个“M",现在已经推出这个公式应该是8 * n^2 - 7 * n + 1,但是这个n的范围达到了10^12次方,只要平方一次就超出long long 的范围了,怎么办呢,用大数?
都试过了,很奇怪,会超时,按照估算的话感觉不会,可能是中间结果比较大吧,这个还在思考,但是10^12平方一次乘以八也只达到了10^25次方级别,所以我们可以用四个__int64来模拟这个结果,这样计算起来就快多了。每一个只存结果的相应的八位,为什么只存八位呢,因为中间要进行平方运算,8位平方以下还好,在long long 的承受范围之内,如果大一点超过long long 就不行了,中间计算的时候相乘就容易溢出,而八位也刚好方便计算。相乘的时候要将大数的对应的位上的long long 两两进行相乘。
还有最后输出结果要注意一点,不能直接输出,中间的数前导0也要输出来,不然看起来就好像少了几个0,反正中间结果用8位的固定格式输出就行了。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 typedef __int64 INT; 9 struct Big10 {11 INT d[4];12 Big()13 {14 memset(d,0,sizeof(d));15 }16 void print()17 {18 int flag = 0;19 for(int i = 3;i >= 0;--i)20 if(d[i] != 0 && !flag)21 {22 printf("%I64d",d[i]);23 flag = 1;24 }25 else if(flag) printf("%08I64d",d[i]);26 puts("");27 }28 };29 Big operator * (Big a,Big b)30 {31 Big c;32 INT flag = 0;33 for(int i = 0;i < 4;++i)34 for(int j = 0;j < 4;++j)35 {36 INT temp = a.d[i] * b.d[j] + flag;37 if(temp) c.d[i+j] += temp % 100000000;38 flag = temp / 100000000;39 }40 return c;41 }42 Big operator - (Big a,Big b)43 {44 Big c;45 for(int i = 0;i < 4;++i)46 {47 if(a.d[i] < b.d[i])48 {49 a.d[i+1] -= 1;50 a.d[i] += 100000000;51 }52 c.d[i] = a.d[i] - b.d[i];53 }54 return c;55 }56 Big operator + (Big a,Big b)57 {58 Big c;59 INT flag = 0;60 for(int i = 0;i < 4;++i)61 {62 INT temp = a.d[i] + b.d[i] + flag;63 c.d[i] = temp % 100000000;64 flag = temp / 100000000;65 }66 return c;67 }68 Big valueof(INT x)69 {70 int f = 0;71 Big ans;72 while(x)73 {74 ans.d[f++] = x % 100000000;75 x /= 100000000;76 }77 return ans;78 }79 int main()80 {81 int T,kase = 1;82 INT a;83 scanf("%d",&T);84 while(T--)85 {86 scanf("%I64d",&a);87 Big ans = valueof(a) * valueof(a);88 ans = ans * valueof(8);89 ans = ans - (valueof(a) * valueof(7));90 ans = ans + valueof(1);91 printf("Case #%d: ",kase++);92 ans.print();93 }94 return 0;95 }