Uva 11401 - Triangle Counting(递推)

Triangle Counting

You are given n rods oflength 1, 2…,n. You have to pick any 3 of them & build a triangle. How many distincttriangles can you make? Note that, two triangles will be considered differentif they have at least 1 pair of arms with different length.

 

Input

The input for each case will have only asingle positive integer (3<=n<=1000000). The end ofinput will be indicated by a case with n<3. This case should notbe processed.

 

Output

For each test case, print the number ofdistinct triangles you can make.

 

SampleInput                                                 

5

8

0

 

 Output for Sample Input

4

22

 

【题意】

   从1-n这n个正整数中选出不同的3个数使得它们能构成一个三角形,求所有方案的数量。


【思路】

   计数问题,假设取出的符合要求的三个数为x,y,z且x最大,则有x<y+z,移项得到x-y<z,同时z<x,所以z的取值范围是(x-y,x)。当y==1时,z无解,当y==2时,z有一组解,…当y==x-1时,z有x-2组解,等差数列求和可知共有(x-1)(x-2)/2组解,但是要注意两点:

(1)确定一个y然后计算z的取值范围时z是有可能和y相等的,而尽管满足构成三角形的条件,但是y==z不符合题意(选3个不同的数字),所以要减去这一部分情况,当y>=floor(x/2)+1时,一定有y==z可以构成三角形,y最大到x-1,所以一共有(x-1)-(floor(x/2)+1)+1==x-1-floor(x/2)种y,z相等的情况,要把它们减去。

(2)这里的方案数其实被算了两次,比如x==5时,枚举y==3时z可以是4,但枚举到y==4时z又可以是3,但这是同一种选择情况,所以要在最后的结果中除2。

所以对于某个x,符合要求的情况数为((x-2)*(x-1)/2-(x-1-floor(x/2)))/2,利用递归来求数列的前n项和即可。

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn = 1e6 + 500;

ll n;
ll s[maxn];

void init() {
	memset(s, 0, sizeof(s));
	for (ll x = 3; x <= 1e6 + 50; x++) {
		s[x] = s[x - 1] + ((x - 2)*(x - 1) / 2 - (x - 1 - x / 2)) / 2;
	}
}

int main() {
	init();
	while (scanf("%lld", &n) == 1 && n >= 3) {
		printf("%lld\n", s[n]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值