Codeforces Round #642 (Div. 3)D. Constructing the Array(廣度優先搜索)

在這裏插入圖片描述
原題鏈接
題意:
給你一個長度爲n的數組a初始元素全爲0,每次把含0最多的子序列的中間元素設爲當前的操作次數,輸出最後不含0的a數組內所有元素。
思路:
一開始看到就感覺和歸併排序和快速排序的寫法差不多,分區間去弄。就寫了以下發現深搜沒寫出來,沒法區分區間內0的個數。既然深搜不行,另一個搜索就是廣搜了,普通的隊列是不行的,因爲這裏是先對含0最多並且靠左邊的區間操作。那麼就用優先隊列定義以下優先級就可以了。比賽的時候沒寫錯了很可惜。。
代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=2e5+10;
int step=0,n;
struct node
{
    int l,r;
    node(int left=0,int right=0):l(left),r(right){}
    bool operator<(const node &a)const
    {
        int s1=r-l+1;
        int s2=a.r-a.l+1;
        if(s1==s2) return l>a.l;//含0一樣多就優先靠左邊
        return (r-l+1)<(a.r-a.l+1);//含0多優先
    }
};
int a[N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        step=0;
        cin>>n;
        priority_queue<node>q;
        q.push(node(1,n));
        while(!q.empty())
        {
            node u=q.top();
            q.pop();
            int l=u.l,r=u.r,mid;
            if((r-l+1)%2==0) mid=(l+r-1)/2;
            else mid=(l+r)/2;
            a[mid]=++step;
            if(l<=mid-1) q.push(node(l,mid-1));//區間存在就入隊
            if(r>=mid+1) q.push(node(mid+1,r));
        }
        for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        cout<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章