BZOJ1105 [POI2007]石头花园SKA 贪心

[POI2007]石头花园SKA

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 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

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 }

 

posted @ 2018-05-02 20:47  Kaiser-  阅读(186)  评论(0编辑  收藏  举报