11401 - Triangle Counting
Time limit: 1.000 seconds
题意:给你n个线段,长度1-n。问可以组成多少不同的三角形
解题思路:
设最大边长为x的三角形有C(x)个,另外两条边长分别为y和z,根据三角不等式有y+z>x。所以z的范围是x-y < z < x。
①根据这个不等式,当y=1时x-1 < z < x,无解;y=2时有一个解(z=x-1);y=3时有两个解(z=x-1或者z=x-2)……直到y=x-1时有x-2个解。根据等差数列求和公式,一共有0+1+2+……+(x-3)+ (x-2) = (x-1)(x-2)/2个解。
②上面的解包含了y=z的情况,而且每个三角形算了两遍。所以要统计出y=z的情况。当y = z的时候x - z < z < x,那么就有x < 2z,有x/2 < z < x,因此满足的z个数有(x-1)-(x/2+1)
那么就要减去这些解,再除以2即可。
③为什么会计算两边呢?可以推一下x=5 y从1开始的情况。就会发现三角形会重复两次。
C(x)=((i-2)*(i-1)/2-((i-1)-(i/2+1)))/2;;原题要求的是"最大边长不超过n的三角形数目F(n)",则F(n)=C(1)+C(2)+…+C(n)。写成递推式就是F(n) = F(n-1) + C(n)。
AC代码:
#include <stdio.h> #include <math.h> #include <vector> #include <queue> #include <string> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 1000002; LL f[MAXN]; int main() { f[3]=0; for(LL i=4;i<MAXN;i++) f[i]=f[i-1]+((i-2)*(i-1)/2-((i-1)-(i/2+1)))/2; int n; while(scanf("%d",&n)){ if(n<3)break; printf("%lld\n",f[n]); } return 0; }
版权声明:本文为博主原创文章,转载请注明出处。
时间: 2024-10-12 17:34:47