首先了解欧拉示性数公式:
平面上有V个点,E条互不相交的直线,划分出F个区域,符合V-E+F=2这个公式1,可以画图推导
接着还得了解一个公式:N条直线相交于M个点,最后划分出了多少个线段,公式2:N+2*M
接着继续看这个问题:求一个圆上取N个点,最多把圆划分成几个区域
首先想下N个点两两之间构成直线,最后可以构成多少条直线呢?
不就是C(N,2)么
还得想下在圆内一共有多少个交点,从直线考虑太复杂了,我们可以发现圆上每4个点构成一个内部的交点,所以数量不就是C(N,4)么
最后总的点数V就是C(N,4)+N(套用了公式2)
总的边数就是C(N,2)+2*C(N,4)+N
最后套用公式1:F=E-V+1(因为只算圆内,所以外围那个大区域减掉),C(N,2)+2*C(N,4)+N-(C(N,4)+N)+1=C(N,2)+C(N,4)+1
附上AC代码:
此处又使用了一个组合数打表,可以优化下时间
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
ll s[maxn][5];
void mt()
{
for(int i=0;i<maxn;i++){
s[i][0]=1;
}
for(int i=1;i<maxn;i++){
for(int j=1;j<5;j++){
s[i][j]=s[i-1][j-1]+s[i-1][j];
}
}
}
int main()
{
mt();
ll n;
while(~scanf("%lld",&n)){
printf("%lld\n",s[n][2]+s[n][4]+1);
}
return 0;
}