有n根长度不同的木棒,随意选取三根凑一个合法的三角形,求总拼凑方案的数量(2018腾讯软件开发-后台开发方向秋招补考试题第三题)

本文持续更新地址:https://haoqchen.site/2018/11/08/triangle-numbers

题目:

有n根长度不同的木棒,随意选取三根凑一个合法的三角形,求总拼凑方案的数量。对于两个方案,只要有一根木棒的长度不同,则视为不同拼凑方案。

输入描述

第一行为正数t(0 <= t <= 10),表示测试用例数

接下来每两行一个测试数据,第一行一个整数n(3 <= n <= 2000)表示木棒数量

第二行n个不一样的正整数li(1 <= li <= 10^9),表示每根木棒的长度。

输出描述

对于每一个测试用例,输出一个正整数表示方案数

示例


2
4
14 21 94 35
6
10 16 87 43 51 75
 

代码

using namespace std;

typedef unsigned int T;

int triangle_nums(T* data, int size)
{
	int counts = 0;
	sort(data, data + size);
	for (int x = 0; x < size-2; ++x){
		for (int y = x + 1; y < size - 1; ++y){
			T xy = data[x] + data[y];
			for (int z = y + 1; z < size; ++z){
				if (xy > data[z]){
					//if ((data[z] + data[x]) > data[y] && (data[z] + data[y]) > data[x])
						++counts;
				}
				else{
					break;
				}
			}
		}
	}
	return counts;
}

int main(int argc, char** argv)
{
	int t;
	int n;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> t;
	if (t < 1 || t > 10)
		return 0;
	T* l = new T[2000];
	while (t--){
		cin >> n;
		if (n < 3 || n > 2000){
			delete[]l;
			return 0;
		}
		for (int i = 0; i < n; ++i)
			cin >> l[i];
		cout << triangle_nums(l, n) << endl;
	}
	delete[]l;
	return 0;
}

思路

一开始使用暴力求解,三层遍历,然后x+y>z&&y+z>x&&x+z>y。但复杂度太大,达到了n^3,后面超出时间,只通过了50%。后来想到了先从小到大排序(时间复杂度nlog(n))。再进行x+y>z,这样只要某个z不满足条件,后续的z也肯定不满足,就可以提前退出。修改后增加到60%左右,同样出现了超时,完全没辙了。最后一分钟仔细思考发现,如果是已经排序了的,只要确保x+y>z就可以,因为y+z>x&&x+z>y这个时候是肯定满足的。最后注释掉代码中的一个if就100%了。

 

posted @ 2018-11-08 21:12  浩劫Calamity  阅读(859)  评论(0编辑  收藏  举报