Problem
codeforces.com/gym/101097/attachments
vjudge.net/contest/160830#problem/I
Reference
blog.csdn.net/dt2131/article/details/70880833
Meaning
有 k 种颜色的边,每种有 ni 条,问能否从这些边中选出其中 3 条颜色不同的边组成三角形。
Analysis
看 vj 中几个 dalao 的代码,思路大概是:将所有边(记颜色和长度)放在一起,按长度排序,从前往后枚举,每次找尽量相邻的 3 条边,如果有同色的边聚在一起,就取其中最长的边(但第 3 条边取最短那条)。然后对找到的这 3 条边判锻是否满足题意,直到找到满足的 3 条边,或者全部搜完。
可能是选尽量近的三条边更有可能组成三角形吧。
Code
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int K = 50, N = 1000000;
struct edge
{
int id, len;
bool operator < (const edge &e) const
{
return len < e.len;
}
} stick[N];
int main()
{
freopen("sticks.in", "r", stdin);
freopen("sticks.out", "w", stdout);
int k;
scanf("%d", &k);
int num = 0;
for(int id=1, n; id<=k; ++id)
{
scanf("%d", &n);
while(n--)
{
scanf("%d", &stick[num].len);
stick[num++].id = id;
}
}
sort(stick, stick + num);
for(int a=0, b, c; a<num; a=b)
{
/* 第一条边去同色的一段中的最长边 */
while(a+1 < num && stick[a+1].id == stick[a].id)
++a;
b = a + 1;
/* 第二条边也类似第一条边 */
while(b+1 < num && stick[b+1].id == stick[b].id)
++b;
c = b + 1;
/* 第三条边取最短,要判颜色和三角形不等式 */
if(c < num && stick[c].id != stick[a].id &&
stick[a].len + stick[b].len > stick[c].len)
{
printf("%d %d %d %d %d %d\n",
stick[a].id, stick[a].len, stick[b].id,
stick[b].len, stick[c].id, stick[c].len);
return 0;
}
}
puts("NIE");
return 0;
}