CF 238B Boring Partition

来源:互联网 发布:以撒的结合胎衣mac版 编辑:程序博客网 时间:2024/04/29 23:48

题目链接:http://codeforces.com/contest/238/problem/B


题目大意:

把一个数组中的数分成两部分

f(ai,aj) = (ai和aj在同一部分)? ai+aj : ai+a[j]+h (i != j)

求最小的godness = max{ f(ai,aj) } - min{ f(ai,aj) }.


题目思路:

我的歪解:

先求出a[]最大值max_a,最小值min_a.

(1)max_a和min_a在一同一部分

(2)max_a和min_a不在同不一部分

在(1)的时候把数组扫一遍,放1时更优就放1,否则放2

同理对(2)也这样处理.

这个证明起来很烦的说。。。

大神的正解:

同样分这两种状况

(1)全在同一部分

(2)min_a单独一部分

先把a[]排序一下,这样a[n]=max_a,a[1]=min_a。

首先我们要知道最小的最大f=a[n]+a[n-1],最大的最小f=a[1]+a[2]+h。

所以最有值是a[n]+a[n-1]-a[1]+a[2]+h,不过这个值不一定能取到。

对于(1)godness=a[n]+a[n-1]-a[1]-a[2]。

对于(2)godness=max(a[n]+a[n-1],a[n]+a[1]+h)-min(a[1]+a[2]+h,a[2]+a[3])。

证明的话相对我的方法比较简单(也挺烦),罗列一下关系,推导。


代码:

#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <math.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define ls rt<<1#define rs ls|1#define lson l,mid,ls#define rson mid+1,r,rs#define middle (l+r)>>1#define eps (1e-8)#define type int#define clr_all(x,c) memset(x,c,sizeof(x))#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))#define MOD 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define _max(x,y) (((x)>(y))? (x):(y))#define _min(x,y) (((x)<(y))? (x):(y))#define _abs(x) ((x)<0? (-(x)):(x))#define getmin(x,y) (x= (x<0 || (y)<x)? (y):x)#define getmax(x,y) (x= ((y)>x)? (y):x)template <class T> void _swap(T &x,T &y){T t=x;x=y;y=t;}int TS,cas=1;const int M=100000+5;int n,h;struct node{    int a,id;    void read(int i){scanf("%d",&a),id=i;}    bool operator < (const node &t) const{        return a < t.a;    }}p[M];int pos[2][M],ans[2];void run(){    int i,j;    for(i=1;i<=n;i++) p[i].read(i);    if(n<3) puts("0\n1 1");    else{        sort(p+1,p+n+1);        int mmax,mmin;        int t1,t2,x1,y1,x2,y2;        int max_in_1,max_in_2,min_in_1,min_in_2;        pos[0][p[n].id]=2,pos[0][p[1].id]=1;        min_in_2=p[n].a,max_in_1=p[1].a;        mmax=mmin=p[n].a+p[1].a+h;        for(i=2;i<n;i++){            x1=_max(mmax,p[n].a+p[i].a+h);            y1=_min(mmin,p[1].a+p[i].a);            t1=x1-y1;            x2=_max(mmax,_max(p[n].a+p[i].a,max_in_1+p[i].a+h));            y2=_min(mmin,_min(min_in_2+p[i].a,p[1].a+p[i].a+h));            t2=x2-y2;            if(t1<t2) mmax=x1,mmin=y1,pos[0][p[i].id]=1,getmax(max_in_1,p[i].a);            else mmax=x2,mmin=y2,pos[0][p[i].id]=2,getmin(min_in_2,p[i].a);        }        ans[0]=mmax-mmin;                pos[1][p[n].id]=2,pos[1][p[1].id]=2;        mmax=mmin=p[n].a+p[1].a;        min_in_1=INF,max_in_1=-INF;        for(i=2;i<n;i++){            x1=_max(mmax,p[n].a+p[i].a+h);            y1=_min(mmin,_min(min_in_1+p[i].a,p[1].a+p[i].a+h));            t1=x1-y1;            x2=_max(mmax,_max(max_in_1+p[i].a+h,p[n].a+p[i].a));            y2=_min(mmin,p[1].a+p[i].a);            t2=x2-y2;            if(t1<t2) mmax=x1,mmin=y1,pos[1][p[i].id]=1,getmin(min_in_1,p[i].a),getmax(max_in_1,p[i].a);            else mmax=x2,mmin=y2,pos[1][p[i].id]=2;        }        ans[1]=mmax-mmin;        if(ans[0]<ans[1]){            for(printf("%d\n",ans[0]),i=1;i<=n;i++)                printf("%d%c",pos[0][i],(i==n)? '\n':' ');        }else{            for(printf("%d\n",ans[1]),i=1;i<=n;i++)                printf("%d%c",pos[1][i],(i==n)? '\n':' ');        }    }}void preSof(){}int main(){    //freopen("input.txt","r",stdin);    //freopen("output.txt","w",stdout);    preSof();    //run();    while(~scanf("%d%d",&n,&h)) run();    //for(scanf("%d",&TS);cas<=TS;cas++) run();    return 0;}

代码(正解):

#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <math.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define ls rt<<1#define rs ls|1#define lson l,mid,ls#define rson mid+1,r,rs#define middle (l+r)>>1#define eps (1e-8)#define type int#define clr_all(x,c) memset(x,c,sizeof(x))#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))#define MOD 1000000007#define inf 0x3f3f3f3f#define pi acos(-1.0)#define _max(x,y) (((x)>(y))? (x):(y))#define _min(x,y) (((x)<(y))? (x):(y))#define _abs(x) ((x)<0? (-(x)):(x))#define getmin(x,y) (x= (x<0 || (y)<x)? (y):x)#define getmax(x,y) (x= ((y)>x)? (y):x)template <class T> void _swap(T &x,T &y){T t=x;x=y;y=t;}int TS,cas=1;const int M=100000+5;int n,h,a[M];void run(){    int i,j;for(i=1;i<=n;i++) scanf("%d",&a[i]);if(n==2){puts("0\n1 1");return;}j=min_element(a+1,a+n+1)-a;sort(a+1,a+n+1);int t1=a[n]+a[n-1]-(a[1]+a[2]);int t2=_max(a[n]+a[n-1],a[n]+a[1]+h)-_min(a[1]+a[2]+h,a[2]+a[3]);if(t1<t2) j=-1;printf("%d\n",_min(t1,t2));for(i=1;i<=n;i++)printf("%d%c",(i==j)? 1:2,(i==n)? '\n':' ');}void preSof(){}int main(){    //freopen("input.txt","r",stdin);    //freopen("output.txt","w",stdout);    preSof();    //run();    while(~scanf("%d%d",&n,&h)) run();    //for(scanf("%d",&TS);cas<=TS;cas++) run();    return 0;}


原创粉丝点击