POI2014Bricks

来源:互联网 发布:mac 双系统 win7 驱动 编辑:程序博客网 时间:2024/06/15 14:36

POI2014 Bricks

正解的话是贪心,就是先把剩下最多的放到现在这个地方来,如果有多个最多的,那么就把颜色与最后一个颜色相同的取出来,不然就随便放一个.

然后用堆来维护这个信息,所以正解是O(nlogn)的.

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#define M 1000005#define biubiu {puts("0");exit(0);}using namespace std;void Rd(int &res){    res=0;char p;    while(p=getchar(),p<'0');    do{        res=(res<<1)+(res<<3)+(p^48);    }while(p=getchar(),p>='0');}int n,st,ed;struct W{    int last,val;    bool operator <(const W &a)const{        if(last!=a.last)return last<a.last;        else return val!=ed;    }};priority_queue<W>q;int ans[M];int main(){    Rd(n),Rd(st),Rd(ed);    int tot=0;    for(int i=1;i<=n;i++){        int x;Rd(x);tot+=x;        if(n==1&&x>=2)biubiu        if(i==st)x--;        if(i==ed)x--;        if(n==1){            printf("1\n");            return 0;        }        if(x<0)biubiu;        q.push((W){x,i});    }    ans[1]=st,ans[tot]=ed;    for(int i=2;i<tot;i++){        W tp=q.top();q.pop();        if(tp.val==ans[i-1]){            W tp2=q.top();q.pop();            q.push(tp);            if(tp2.last==0)biubiu            tp2.last--;            q.push(tp2);            ans[i]=tp2.val;        }else {            ans[i]=tp.val;            tp.last--;            q.push(tp);        }    }    if(ans[tot-1]==ans[tot])biubiu    bool f=false;    for(int i=1;i<=tot;i++){        if(f)putchar(' ');f=true;        printf("%d",ans[i]);    }    return 0;}

对于100W的数据也是能过的,但是由于对被POI100W的数据的常数支配的恐惧,从而开发出了近似O(n)的方法…(不会算复杂度)

首先我们明确,一组相同的数字要放进一个序列,一定是隔一个放一个这组数字,这样才能放进去最多的这种数字,这是很显然的.

然后因为我们是一种数字一种数字往里面放的,势必会引起一些数字会连在一起,这样的话,我们下一次的数字要优先放在那些连在一起的数字之间.

这样的话,我们把这些需求存在一个数组里,每一次优先满足这些需求,然后再贪心地去加入数字.

然后实现的话,用链表可以完成O(1)的插入,所以速度还是不错的.

因为每种数字的插入是O(a[i])的(只需要找到a[i]个空位),所以总复杂度是O(a[i])的.

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 1000005#define biubiu {puts("0");exit(0);}using namespace std;void Rd(int &res){    res=0;char p;    while(p=getchar(),p<'0');    do{        res=(res<<1)+(res<<3)+(p^48);    }while(p=getchar(),p>='0');}void Pt(int x){    if(x==0)return;    Pt(x/10);    putchar(x%10^48);}void Ps(int x){    if(x==0)putchar('0');    else Pt(x);}int a[M];struct W{    int fr,val,nx;}Lis[M];int ned[M],T=2;//ned[i]-ned[i].nx是一样的颜色 void Add(int l,int r,int x){//把x插到l,r里面     Lis[l].nx=T,Lis[r].fr=T;    Lis[T].fr=l,Lis[T].nx=r;    Lis[T++].val=x;}int main(){    int n,st,ed,tot=0;Rd(n),Rd(st),Rd(ed);    for(int i=1;i<=n;i++)Rd(a[i]),tot+=a[i];    if(n==1){        if(tot>=2)biubiu        printf("%d\n",st);        return 0;    }    Lis[1].fr=-1,Lis[1].val=st,Lis[1].nx=tot;    Lis[tot].fr=1,Lis[tot].val=ed,Lis[tot].nx=-1;    int tp=0;    a[st]--,a[ed]--;    if(a[st]<0||a[ed]<0)biubiu    for(int i=1;i<=n;i++){        while(tp&&a[i]){            Add(ned[tp-1],Lis[ned[tp-1]].nx,i);            tp--,a[i]--;        }        for(int j=1,be=1;j<=a[i];j++){            while(be!=tot&&(Lis[Lis[be].nx].val==i||Lis[be].val==i))be=Lis[be].nx;            if(be==tot){                for(int k=j;k<=a[i];k++){                    Add(Lis[be].fr,be,i);                    if(Lis[Lis[Lis[be].fr].fr].val==i)ned[tp++]=Lis[Lis[be].fr].fr;                }                if(i==ed)ned[tp++]=Lis[be].fr;                break;            }            Add(be,Lis[be].nx,i);        }    }    if(tp)biubiu    bool f=false;    for(int i=1;~i;i=Lis[i].nx){        if(f)putchar(' ');f=true;        Ps(Lis[i].val);    }    putchar('\n');    return 0;}
0 0
原创粉丝点击