题意:在一张纸上,会有N个"M"形的折线相交。问,这些平面相交最多可以将这张纸划分成多少个区域。
思路:
1.用高中的方法递推就可以啦:现在已经有放了i个"M"形的折线,考虑第i+1个。要想将平面分成最多的区域,应该使第i+1个折线的四条边和其余i个折线的所有边都有交点。这样,会产生4 * 4i个区域。需要注意的是,因为“M”形折线是从纸边界出来的,然后回到纸的边界,这样会再多一个区域。
按照上面的递推可以得到公式: 8n^2 - 7n + 1;
2.还有一个偷懒的方法。其实在平面上,不管用什么样的折线分割,得到的最多区域一定是个二次多项式,用待定系数法,找到三个系数的值,直接解方程就可以了。
注意:因为数很大,要用JAVA写,但是你会发现,正常的方法会TLE。这个时候就要开输入输出挂了。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
public class Main
{
public static void main(String args[]) throws IOException
{
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int T = (int)in.nval;
int i = 1;
while(i <= T) {
in.nextToken();
BigInteger a = BigInteger.valueOf((long)in.nval);
out.println("Case #" + i + ": " + a.multiply(a).shiftLeft(3).subtract(a.multiply(a.valueOf(7))).add(a.ONE));
i+=1;
}
out.flush();
}
}
或者直接上C++大整数:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct BigInteger{
int len;
int a[30];
BigInteger(long long n = 0){
memset(a,0,sizeof(a));
len = 0;
for(;n;n /= 10)
a[len++] = n % 10;
}
void print()
{
for(int i = len - 1; i >=0; --i)
printf("%d",a[i]);
}
};
BigInteger operator +(const BigInteger & A, const BigInteger & B){
BigInteger C;
C.len = max(A.len,B.len);
int r = 0;
for(int i = 0; i < C.len; ++i){
r += A.a[i] + B.a[i];
C.a[i] = r % 10;
r /= 10;
}
while(r){
C.a[C.len++] = r % 10;
r /= 10;
}
return C;
}
BigInteger operator * (const BigInteger & A, const BigInteger & B){
BigInteger C;
C.len = A.len + B.len;
for(int i = 0; i < A.len; ++i){
int r = 0;
for(int j = 0; j < B.len; ++j){
r += A.a[i] * B.a[j] + C.a[i+j];
C.a[i+j] = r % 10;
r /= 10;
}
C.a[i + B.len] = r;
}
while((C.len > 1) && (C.a[C.len-1] == 0)) --C.len;
return C;
}
int main(void)
{
BigInteger eight(8);
BigInteger two(2);
BigInteger nine(9);
int T;
long long N;
scanf("%d", &T);
for(int i = 1; i <= T; ++i){
scanf("%I64d", &N);
if(N == 0){
printf("Case #%d: 1\n",i);
}
else{
N--;
BigInteger A(N);
BigInteger ans = eight * A * A + nine * A + two;
printf("Case #%d: ",i);
ans.print();
puts("");
}
}
return 0;
}