题目描述
对于一个 n n n 个顶点的凸多边形,它的任何三条对角线都不会交于一点。请求出图形中对角线交点的个数。
例如, 6 6 6 边形:
输入格式
输入只有一行一个整数 n n n,代表边数。
输出格式
输出一行一个整数代表答案。
样例 #1
样例输入 #1
3
样例输出 #1
0
样例 #2
样例输入 #2
6
样例输出 #2
15
提示
数据规模与约定
- 对于 50 % 50 \% 50% 的数据,保证 3 ≤ n ≤ 100 3 \leq n \leq 100 3≤n≤100。
- 对于 100 % 100 \% 100% 的数据,保证 3 ≤ n ≤ 1 0 5 3 \leq n \leq 10^5 3≤n≤105。
错误原因一:没思路
这道题可以看成是规律题,但是这个规律不太好想。
题目提示,“它的任何三条对角线都不会交于一点,因此可以得出,”两边确定一条直线“。
因为我们需要在交点与多边形的边数之间确定联系,所以我们进一步得出,
”四点确定一个交点“。
因此只需要算出 n n n边形的中任意取出四个不同的点的方案数,便是我们想要求的交点个数。
即, n n n边形的交点个数 y = C n 4 = n ( n − 1 ) ( n − 2 ) ( n − 3 1 ∗ 2 ∗ 3 ∗ 4 y = C^4_n = {n(n-1)(n-2)(n-3 \over 1*2*3*4} y=Cn4=1∗2∗3∗4n(n−1)(n−2)(n−3
代码呼之欲出。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull n;
int main()
{
cin >> n;
cout << n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4;
return 0;
}
错误原因二:低估了数据范围
上方代码的虽然将n*(n-1)*(n-2)*(n-3)/1/2/3/4
写成了n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4
以尽可能缩小数据在计算过程中超过范围的可能性,但是结果依旧不尽人意。
将代码进行如下修改,即将long long
类型改为unsigned long long
类型,完全通过。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull n;
int main()
{
cin >> n;
cout << n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4;
return 0;
}
在面对较大的数据范围时,需要特别注意这个细节,避免疏忽带来的失分。
原创不易,感谢支持。