BZOJ1105 [POI2007]石头花园SKA 贪心
[POI2007]石头花园SKA
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 776 Solved: 237
[Submit][Status][Discuss]
Description
Blue Mary是一个有名的石头收藏家。迄今为止,他把他的藏品全部放在他的宫殿的地窖中。现在,他想将他
的藏品陈列在他的花园中。皇家花园是一个边长为1000000000单位的平行于坐标轴的正方形。对于每个石头,Blue
Mary都有一个他想放置的坐标,然后将他告诉他的属下。不幸的是,他忘了告诉他们坐标的顺序(比如无法分辨(
x,y)和(y,x))。属下们,就自己决定了每个石头的具体位置。为了保护他的藏品,Blue Mary决定建造一个篱笆来
保护他们。为了美学的需要,篱笆也被设计为平行于坐标轴的矩形。如果花园的布局知道了,那么就可以知道最短
长度的篱笆的布局。他的属下们需要变换石头的坐标使得篱笆的长度最少。每个石头只能从(x,y)变换为(y,x),由
于每个石头的重量不一样。属下们希望他们移动的石头的重量和最少。
Input
第一行包含一个数n,表示石头的数量
接下来n行分别描述n个石头的初始坐标和重量xi,yi,mi。
(0<=xi,yi<=1000000000,1<=mi<=2000
(2<=n<=1000000)
Output
一行包含两个数由一个空格分割。
最小的篱笆长度和最小的移动的石子的重量和
Sample Input
5
2 3 400
1 4 100
2 2 655
3 4 100
5 3 277
2 3 400
1 4 100
2 2 655
3 4 100
5 3 277
Sample Output
10 200
HINT
2018.4.17修改题面,不需要输出方案了.未重测!
题解:
篱笆的长度最小是第一目标,应当优先考虑。易知,当所有石头的坐标都满足x<=y的时候,即全部在y=x直线的一侧之时,一定能够得到最小的周长,这时的周长就是第一个答案。
而满足这一周长的方式不止一种,可以将这个矩形关于y=x直线做对称,总共有四种可能的情况,全部枚举一遍即可。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define ll long long 8 #define inf 1000000007 9 #define N 1000007 10 11 #define Wb putchar(' ') 12 #define We putchar('\n') 13 #define rg register int 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 19 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 20 return x*f; 21 } 22 inline void write(ll x) 23 { 24 if(x<0) putchar('-'),x=-x; 25 if (x==0) putchar(48); 26 int num=0;char c[20]; 27 while(x) c[++num]=(x%10)+48,x/=10; 28 while(num) putchar(c[num--]); 29 } 30 31 int n,m,ans=inf; 32 int lx=inf,ly=inf,rx=-inf,ry=-inf; 33 struct Node 34 { 35 int x,y,w; 36 }a[N]; 37 38 inline void solve(int lx,int ly,int rx,int ry) 39 { 40 #define judge(x,y) (x>=lx&&x<=rx&&y>=ly&&y<=ry) 41 int res=0; 42 for (int i=1;i<=n;i++) 43 { 44 if (judge(a[i].x,a[i].y)) continue; 45 if (judge(a[i].y,a[i].x)) res+=a[i].w; 46 else return; 47 } 48 #undef judge 49 ans=min(ans,res); 50 } 51 int main() 52 { 53 n=read(); 54 for (int i=1;i<=n;i++) 55 a[i].x=read(),a[i].y=read(),a[i].w=read(); 56 for (int i=1;i<=n;i++) 57 if (a[i].x<a[i].y) 58 { 59 lx=min(lx,a[i].x); 60 ly=min(ly,a[i].y); 61 rx=max(rx,a[i].x); 62 ry=max(ry,a[i].y); 63 } 64 else 65 { 66 lx=min(lx,a[i].y); 67 ly=min(ly,a[i].x); 68 rx=max(rx,a[i].y); 69 ry=max(ry,a[i].x); 70 } 71 solve(lx,ly,rx,ry),solve(lx,ly,ry,rx); 72 solve(ly,lx,rx,ry),solve(ly,lx,ry,rx); 73 write(2ll*(rx+ry-lx-ly)),Wb,write(ans); 74 }