[bzoj1105]石头花园

首先$C/2=x_{max}+y_{max}-x_{min}-y_{min}=max(x_{max},y_{max})-min(x_{min},y_{min})+min(x_{max},y_{max})-max(x_{min},y_{min})$,容易发现前两项都是定值,那么就是要最小化后面的数字
构造:让所有数都满足$x\le y$,那么必然使得$min(x_{max},y_{max})$最小,$max(x_{min},y_{min})$最大,也就是令周长最小
然后考虑最小化重量和,根据上面的构造,我们发现必须要两者同时取到极值才能最小,也就是可以分别构造,不妨枚举最大值的位置和次大值的位置(最小值同理),一共2*2=4种状态分类讨论即可
(注意:要判定无解,因为有可能某两个不同类型(大和小)的值同时出现在一个点中,导致两种情况都不符合)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1000005
4 int n,mx1,mx2,mn1,mn2,ans,x[N],y[N],w[N];
5 int calc(int mx1,int mx2,int mn1,int mn2){
6 int ans=0;
7 for(int i=1;i<=n;i++)
8 if ((x[i]>mx1)||(x[i]<mn1)||(y[i]>mx2)||(y[i]<mn2)){
9 swap(x[i],y[i]);
10 ans+=w[i];
11 if ((x[i]>mx1)||(x[i]<mn1)||(y[i]>mx2)||(y[i]<mn2)){
12 swap(x[i],y[i]);
13 return 2e9;
14 }
15 swap(x[i],y[i]);
16 }
17 return ans;
18 }
19 int main(){
20 scanf("%d",&n);
21 mn1=mn2=1e9;
22 for(int i=1;i<=n;i++){
23 scanf("%d%d%d",&x[i],&y[i],&w[i]);
24 mx1=max(mx1,max(x[i],y[i]));
25 mx2=max(mx2,min(x[i],y[i]));
26 mn1=min(mn1,min(x[i],y[i]));
27 mn2=min(mn2,max(x[i],y[i]));
28 ans+=w[i];
29 }
30 for(int i=0;i<2;i++){
31 for(int j=0;j<2;j++){
32 ans=min(ans,calc(mx1,mx2,mn1,mn2));
33 swap(mn1,mn2);
34 }
35 swap(mx1,mx2);
36 }
37 printf("%lld %d",2LL*(mx1+mx2-mn1-mn2),ans);
38 }
上一篇:apache kafka系列之jmx监控指标参数


下一篇:Team Leader 你不再只是编码, 来炖一锅石头汤吧