题目1:给定一个n个正整数的数组a,问在其中取三个数,同时满足以下两个条件的取法有多少个:
1、这三个数能构成三角形(即任意两数之和大于第三数)
2、这三个数构成的三角形既不是等边三角形,也不是直角三角形。
数据范围:
3 <= n <= 2000
1 <= ai <= 2000
C语言代码:
int cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
int number_san(int *a)
{
int size = sizeof(a) / sizeof(int);
qsort(a, size, sizeof(int), cmp); //按从小到大排序
int num = 0;
for(int i = 0; i < size - 2; ++i){
for(int j = i + 1; j < size - 1; ++j){
for(int k = j + 1; k < size; ++k){
if(a[i] + a[j] <= a[k])
break;
if(a[i] == a[j] && a[i] == a[k])
continue;
if(a[i] * a[i] + a[j] * a[j] == a[k] * a[k])
continue;
++num;
}
}
}
return num;
}
说明:由于使用了暴力遍历,三层循环,即使其中有优化措施,也导致程序时间复杂度过高,暂没想到更高的算法。
题目2:
给定一个n个正整数的数组a,问在其中取三个数,同时满足以下两个条件的取法有多少个:
1、这三个数能构成三角形(即任意两数之和大于第三数)
2、这三个数不能是重复,即234和324是相同的。
C++语言代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
int ans=0;
int main()
{
cin>>n;
vector<int> res;
vector<vector<int>> ret;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
res.push_back(x);
}
sort(res.begin(),res.end());
for(int i=0;i<n-2;i++)
for(int j=i+1;j<n-1;j++)
{
for(int k=j+1;k<n;k++)
{
if(res[i]+res[j]>res[k])
{
ans++;
vector<int> h;
h.push_back(res[i]);
h.push_back(res[j]);
h.push_back(res[k]);
ret.push_back(h); //保存已有数据
}
}
}
sort(ret.begin(),ret.end());
for(int i=0;i<ret.size();i++)
{
if(ret[i]==ret[i+1]) ans--;
}
cout<<ans;
return 0;
}