BZOJ3523[Poi2014]Bricks——貪心+堆
阿新 • • 發佈:2018-09-05
tar 倒數 truct include pri bzoj ios operator 範圍
2 3 3
題目描述
有n種顏色的磚塊,第i種顏色的磚塊有a[i]個,你需要把他們放成一排,使得相鄰兩個磚塊的顏色不相同,限定第一個磚塊的顏色是start,最後一個磚塊的顏色是end,請構造出一種合法的方案或判斷無解。
輸入
第一行3個數,n,start,end。
第二行n個數,a[i]。
輸出
令m=sigma(a[1..n])。
如果有解輸出m個數。
無解輸出0。
樣例輸入
3 3 12 3 3
樣例輸出
3 2 1 3 2 3 2 1提示
【數據範圍】
n,m≤1000000,1≤start,end≤n
為了防止排到後面一樣的磚塊太多排不開,所以要貪心的每個位置排當前剩余塊數最多的顏色的磚塊,如果有多個顏色剩余最多,要優先考慮和末尾顏色相同的來防止倒數第二個和最後一個顏色相同。用堆維護當前位置塊數最多的顏色取就好了。
#include<set> #include<map> #include<cmath> #include<queue> #include<stack> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int s,t,n,m; bool flag; struct node { int x,y; }; bool operator < (node a,node b) { if(a.x!=b.x) { return a.x<b.x; } if(a.y==t) { return false; } return true; } priority_queue<node>q; int ans[1000010]; int main() { scanf("%d%d%d",&n,&s,&t); node miku,jhin; for(int i=1;i<=n;i++) { scanf("%d",&miku.x); m+=miku.x; miku.y=i; if(i==s) { miku.x--; } if(i==t) { miku.x--; } if(miku.x<0) { printf("0"); return 0; } q.push(miku); } ans[1]=s; ans[m]=t; for(int i=2;i<m;i++) { miku=q.top(); flag=false; q.pop(); if(miku.y==s) { jhin=miku; if(!q.empty()) { miku=q.top(); } else { printf("0"); return 0; } q.pop(); flag=true; } s=ans[i]=miku.y; if(miku.x>1) { q.push((node){miku.x-1,miku.y}); } if(flag) { q.push(jhin); } } if(ans[m-1]==ans[m]) { printf("0"); return 0; } for(int i=1;i<=m;i++) { printf("%d ",ans[i]); } }
BZOJ3523[Poi2014]Bricks——貪心+堆