题意简述
给你一些木棍,每个木棍有长度和颜色。输出一种方案,选择三个木棍,使得颜色不一样且能拼成一个三角形。开 S P J SPJ SPJ,多解输出任意一个。
木棍数量 n < = 1000000 n<=1000000 n<=1000000,颜色数量 k < = 50 k<=50 k<=50。
思路框架
按长度排序,每次更新答案。
具体思路
首先木棍显然是无序的。无序的问题,就先无脑排序一下(如果复杂度能承受)。没问题的。
然后我们用一个长度为 3 3 3的数组表示答案。每次枚举 i i i,表示我们必须要把 i i i放到答案中(如果合法)
如果我们的答案中已经有一个和 i i i同颜色的木棍,那么我们肯定是换掉来的好,因为 i i i的长度肯定大于这根木棍的长度。(我们排过序,记得么)
然后如果没有相同的颜色,就用它换掉最短的那个木棍。这样显然也是更好的。
然后检测一下是否合法。如果合法,就输出答案,然后直接退出程序即可。
代码
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 1666666
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
struct node
{
int col,len;
}a[N];int cnt=0;
bool operator<(node a,node b){return a.len<b.len;}
int k;
void R1(int &x)
{
x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=(f==1)?x:-x;
}
void Input()
{
R1(k);
cnt=0;
F(i,1,k)
{
int n;R1(n);
F(j,1,n)
{
int len;R1(len);
a[++cnt]=(node){i,len};
}
}
}
node ans[4];
void Soviet()
{
sort(a+1,a+cnt+1);
FK(ans);
F(i,1,cnt)
{
bool flag=false;
F(j,1,3)
{
if (a[i].col==ans[j].col)//相同颜色
{
ans[j].len=a[i].len;
flag=true;
}
}
if (!flag)//没有相同的颜色
{
ans[1]=a[i];//换掉最小的
}
sort(ans+1,ans+4);
if (ans[1].len+ans[2].len>ans[3].len)//检测
{
F(j,1,3) printf("%d %d ",ans[j].col,ans[j].len);
putchar('\n');
return;
}
}
puts("NIE");
}
#define Flan void
Flan IsMyWife()
{
Input();
Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}
博客介绍了如何解决POI2011竞赛中的PAT-Sticks问题,即给定多个颜色和长度的木棍,找出能构成三角形的三个不同颜色的木棍。通过按长度排序并使用SPJ进行多解判断,采用枚举和替换策略优化解决方案,确保在不超过特定限制的情况下找到合法组合。
479

被折叠的 条评论
为什么被折叠?



