UVA Triangle Counting 11401【几何+数学】

11401 - Triangle Counting

Time limit: 1.000 seconds


UVA Triangle Counting 11401【几何+数学】_第1张图片


题意:给你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;
}


你可能感兴趣的:(UVA Triangle Counting 11401【几何+数学】)