Description
由正 n n 边形的顶点构成的所有三角形中,有多少种互不全等的三角形
Input
第一行为一个整数,表示数据的组数。接下来对于每组数据:
第一行为一个整数 n(3≤n≤109) n ( 3 ≤ n ≤ 10 9 ) ,表示正多边形的边数。
Output
对于每组数据,输出一行:
第一行为一个整数,表示互不全等三角形的个数。
Sample Input
1
3
Sample Output
1
Solution
给 n n 个顶点按顺时针编号,考虑三角形三个顶点的编号差,问题即转化为求满足, a≤b≤c a ≤ b ≤ c , a+b+c=n a + b + c = n 的三元组 (a,b,c) ( a , b , c ) 的个数,进一步的即为求满足 a,b,c≥0 a , b , c ≥ 0 , a≤b≤c a ≤ b ≤ c , a+b+c=n−3 a + b + c = n − 3 的三元组 (a,b,c) ( a , b , c ) 个数,令 n=n−3 n = n − 3 ,答案分成四部分,即 a<b<c a < b < c , a=b<c a = b < c , a<b=c a < b = c , a=b=c a = b = c
对于 a=b=c a = b = c 的情况,需要 3|n 3 | n 才有一种方案 ,方案数记为 ans1 a n s 1
对于 a=b<c a = b < c 的情况,显然 a,b a , b 取值区间为 [0,⌊n3⌋] [ 0 , ⌊ n 3 ⌋ ] ,方案数为 ans2=⌊n3⌋+1 a n s 2 = ⌊ n 3 ⌋ + 1 ,注意当 3|n 3 | n 时需要减 1 1 表示去掉的情况
对于 a<b=c a < b = c 的情况,假设方案数为 ans3 a n s 3 ,如果 n n 为奇数,那么的取值集合为 [0,⌊n3⌋] [ 0 , ⌊ n 3 ⌋ ] 中的奇数,共 ⌊⌊n3⌋+12⌋ ⌊ ⌊ n 3 ⌋ + 1 2 ⌋ 个,如果 n n 为偶数,那么的取值集合为 [0,⌊n3⌋] [ 0 , ⌊ n 3 ⌋ ] 中的偶数,共 ⌊n3⌋+1−⌊⌊n3⌋+12⌋ ⌊ n 3 ⌋ + 1 − ⌊ ⌊ n 3 ⌋ + 1 2 ⌋ 个,同样的注意 3|n 3 | n 时需要减 1 1 表示去掉的情况
对于 a<b<c a < b < c 的情况,假设方案数为 ans4 a n s 4 ,由于满足 a,b,c≥0,a+b+c=n a , b , c ≥ 0 , a + b + c = n 的方案数组成即为 ans1+3⋅(ans2+ans3)+6⋅ans4 a n s 1 + 3 ⋅ ( a n s 2 + a n s 3 ) + 6 ⋅ a n s 4 ,而该方案数即为把 n n 个物品放到个盒子中且盒子可以为空的方案数,即由插板法知答案为 C2n+2 C n + 2 2 ,以此求出 ans4 a n s 4
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100001;
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
n-=3;
ll sum=(ll)(n+1)*(n+2)/2;
int ans1=n%3==0?1:0;//a=b=c
int ans2=n/3+1-ans1;//a=b<c
int ans3;
if(n&1)ans3=(n/3+1)/2-ans1;
else ans3=n/3+1-(n/3+1)/2-ans1;
sum-=(ans1+3ll*ans2+3ll*ans3);
sum/=6;//a<b<c
sum=sum+ans1+ans2+ans3;
printf("%lld\n",sum);
}
return 0;
}