题型:高精度
题意:用N个“M”分割平面,问最多可以分割成多少个平面。
分析:
通常这一类用折线分割平面的题,我都不太会推导。现在跟gx god学了一招,凡是这一类折线切割平面的题,公式都形如ax^2+bx+c,然后根据给出的样例数据,一般就能列出一个三元方程组,轻松求解a、b、c。
此题数据高达10^12,所以采用大数方法。网络赛的时候,出题人用读入卡JAVA,所以我采用C++高精度解决。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int M = 32;
class Hp { //高精度类
int len,s[M];
public:
void init(char ch[]) {
len=1;
mt(s,0);
int i=0;
while(ch[i]=='0'&&ch[i]!=0) i++;
if(ch[i]!=0) {
len=strlen(ch)-i;
for(i=0; i<len; i++) {
s[i]=ch[len-i-1]-48;
}
}
}
void print() { //输出
int i=len-1;
while(s[i]==0&&i>0) i--;
for(; i>=0; i--) {
printf("%d",s[i]);
}
}
void add(int x) { //高精度加单精度
int temp=0;
s[0]+=x;
while(s[temp]>9) {
s[temp]-=10;
temp++;
s[temp]++;
}
if(s[len]!=0) len++;
}
void subtract(Hp a) { //高精度减高精度
for(int i=0; i<len; i++) {
s[i]-=a.s[i];
if(s[i]<0) {
s[i]+=10;
s[i+1]--;
}
}
while(len>1&&s[len-1]==0) len--;
}
void multiply(int b) { //高精度乘单精度
int temp=0;
for(int i=0; i<len; i++) {
temp+=s[i]*b;
s[i]=temp%10;
temp/=10;
}
s[len++]=temp;
while(s[len-1]>10) {
s[len]+=s[len-1]/10;
s[len-1]%=10;
len++;
}
while(len>1&&s[len-1]==0) len--;
}
void multiply(Hp b) { //高精度乘高精度
Hp c;
mt(c.s,0);
for(int i=0; i<len; i++) {
for(int j=0; j<b.len; j++) {
c.s[i+j]+=s[i]*b.s[j];
c.s[i+j+1]+=c.s[i+j]/10;
c.s[i+j]%=10;
}
}
len=len+b.len;
for(int i=0; i<len; i++) {
s[i]=c.s[i];
}
while(len>1&&s[len-1]==0) len--;
}
}A,B;
int main(){
int _,Cas = 0;
scanf("%d",&_);
char str[32];
while(_--){
scanf("%s",str);
A.init(str);
B.init(str);
A.multiply(B);
A.multiply(8);
B.multiply(7);
A.subtract(B);
A.add(1);
printf("Case #%d: ",++Cas);
A.print();
puts("");
}
return 0;
}