题目描述
对于一个N个定点的凸多边形,他的任何三条对角线都不会交于一点。请求楚图形中对角线交点的个数。
例如,6边形:
输入输出格式
输入格式:第一行一个n,代表边数。
输出格式:第一行输出交点数量
输入输出样例
说明
50%的测试数据 3≤N≤100;
100%的测试数据 3≤N≤100000.
思路一:
公式法:首先我们易求得对角线条数为:n*(n-3)/2,在经过一些排列组合的技巧,就可以得出。即n*(n-1)*(n-2)*(n-3)/24,看了一眼数据范围,大约估摸比long long大了几位,本准备打一波高精,但突然想起了unsigned long long,于是用计算器算了一下100000的答案,发现正好在范围里面,于是我就打程序。其中有一个小细节,如果按照原来的公式光乘法就会爆范围的,于是就换一种形式:n*(n-1)/2*(n-2)/3*(n-3)/4,这样就可以过了。
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
unsigned long long n;
cin>>n;
cout<<(n*(n-1)/2*(n-2)/3*(n-3)/4)<<endl;
return 0;
}
思路二:
高精度:
n 交点
2 = 0
3 = 0
4 = 1
5 = 5
6 = 15
7 = 35
8 = 70
... ...
对数列每相邻两项作差
得到
a[3]-a[2] = 0
a[4]-a[3] = 1
a[5]-a[4] = 4
a[6]-a[5] = 10
a[7]-a[6] = 20
a[8]-a[7] = 35
真相就要浮出水面了!
再做差得到
1
3
6
10
15
有没有很熟悉了?得到结论:再做差
1
2
3
4
5
...
所以,类似的这种题都可以坚持不懈做差找规律
#include<cstdio>
long long a1[100000];
long long a2[100000];
long long a3[100000];
int main()
{
long long n;
scanf("%lld",&n);
int t=0;
for(int i=1;i<=n;i++)
{
a1[i]=a1[i-1]+i;//这里生成1,3,6,10序列
}
for(int i=1;i<=n;i++)
{
a2[i]=a2[i-1]+a1[i];//这里生成1,4,10,20序列
}
for(int i=1;i<=n;i++)
{
a3[i]=a3[i-1]+a2[i];//这里生成答案序列:1,5,15,35
}
printf("%lld",a3[n-3]);
return 0;
}