题意略过。
感觉这种题目还是需要找结论,一开始想的怎么用算法固定套,想了半天感觉好像可以直接做,,
结论就是,,为了保证周长最短,肯定要把所有的点放在一边,即y=x的左边或者右边,然后四种情况一一枚举找最小代价就好了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define judge(x,y) (x>=lx&&x<=rx&&y>=ly&&y<=ry)
using namespace std;
const int N=1e6+5;
const int inf=0x7fffffff;
struct node
{
int x,y,w;
}a[N];
int n,m,ans=inf;
bool vis[N],bz[N];
inline void cal(int lx,int ly,int rx,int ry)
{
int res=0;
memset(vis,0,sizeof(vis));
fo(i,1,n)
{
if (judge(a[i].x,a[i].y))continue;
if (judge(a[i].y,a[i].x))
vis[i]=1,res+=a[i].w;
else return;
}
if (res<ans)
{
ans=res;
memcpy(bz,vis,sizeof(bz));
}
}
int main()
{
scanf("%d",&n);
int lx=inf,ly=inf,rx=-inf,ry=-inf;
fo(i,1,n)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
fo(i,1,n)
{
if (a[i].x<a[i].y)
{
lx=min(lx,a[i].x);
ly=min(ly,a[i].y);
rx=max(rx,a[i].x);
ry=max(ry,a[i].y);
}
else
{
lx=min(lx,a[i].y);
ly=min(ly,a[i].x);
rx=max(rx,a[i].y);
ry=max(ry,a[i].x);
}
}
cal(lx,ly,rx,ry);
cal(lx,ly,ry,rx);
cal(ly,lx,rx,ry);
cal(ly,lx,ry,rx);
printf("%lld %d\n",2ll*(rx+ry-lx-ly),ans);
fo(i,1,n)
if (bz[i])printf("1");
else printf("0");
printf("\n");
return 0;
}