出处:
https://blog.youkuaiyun.com/yjx_xx/article/details/36035947
此题初识欧拉公式 V - E + F = 2.
其中V是顶点(即所有线段的断点数加上交点数),E是边数(即n段椭圆弧加上这些线段被切成的段数),F是面数(即土地块数加上椭圆外那个无穷大的面)。
题目:有一块椭圆的地,你可以在边界上选n个点,并两两连接得到n(n-1)/2条线段。它们最多能把土地分成多少个部分?
解:
最优方案不会让三条线段交于一点。
欧拉公式:V-E+F=2.其中V是顶点(即所有线段的断点数加上交点数),E是边数(即n段椭圆弧加上这些线段被切成的段数),F是面数(即土地块数加上椭圆外那个无穷大的面)。
换句话说,只需求出V和E,答案就是E-V+1;
不管是定点还是边,计算时都要枚举一条从固定点出发(所以最后要乘以n)的所有对角线。假设该对角线左边有i个点,右边有n-2-i个点,则左右两边的点两两搭配后在这条对角线上形成了i*(n-2-i)个焦点,得到了i*(n-2-i)+1条线段。注意:每个交点被重复计算了4次,而每条线段被重新计算了2次。
#include <stdio.h>
int main()
{
int n,V,E,sumv,sume,i;
while(~scanf("%d",&n))
{
sumv=sume=0;
for(i=0;i<n-1;i++)
sumv+=i*(n-2-i);
for(i=0;i<n-1;i++)
sume+=i*(n-2-i)+1;
V=n+n*sumv/4;
E=n+n*sume/2;
printf("%d\n",E-V+1);
}
return 0;
}
再来多一题:
视频网址:https://www.bilibili.com/video/av19849697
问:n个点能把一个圆分割成多少个区域。
我们通过欧拉公式 F=E-不包括最外围的区域)
那么设n个点能形成的直线为L, ,因为每两个点就能构成一条直线
,这表示内部的点,每4个外点就能构造出一个内部点(相当于两条对角线相交于一点)。
最后我们来求E,易得两条对角线相交于一个点,会多出两条边,3条对角线相交于两个点,会多出2*2条边,那么即是n条对角线相交于m个点,会多出2*m个点,最后E=。
所以F=。
#include<bits/stdc++.h>
using namespace std;
long long C(int n, int m)
{
long long s=1;
if(n < m)
s=0;
else if (n == m || m == 0)
s=1;
else
for(int i=1; i<=m; i++)
s = s * (n - i + 1) / i;
return s;
}
int main(){
int n;
while(cin>>n){
cout<<C(n,4)+C(n,2)+1<<endl;
}
return 0;
}