5.15每日一题题解

Constructing the Array

涉及知识点:

  • 优先队列

solution:

  • (首先可以很容易想到该题的朴素做法:循环n次,每次找到最长长度的连续0子串,按照r-l+1的奇偶性进行赋值,再把分割出来的0子串加入)
  • (很显然,朴素做法每一次操作都需要找到最长长度子串,如果每一次sort的话时间复杂度将会是 O(n*n!))
  • (所以,涉及到需要多次sort的题目,我们可以优先考虑优先队列)
  • (我们只需要用pair或者结构体来存储左边界和有边界,每一次取出差值最大的那个,按照奇偶性赋值并且拆分,就可以得到我们想要的答案了)
  • (当然比较函数需要我们自己去写,优先队列的比较函数重载可以有小于大于号重载和括号重载,这里根据自己习惯选择)

std:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6;

int a[N];

typedef pair<int,int> PII;

struct cmp
{
    bool operator()(PII a,PII b)
    {
        if((a.second-a.first)==(b.second-b.first))
        {
            return a.first > b.first;
        }
        else return (a.second-a.first)<(b.second-b.first);
    }
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int t;
    cin >> t;
    while(t -- )
    {
        int n;
        cin >> n;
        priority_queue<PII,vector<PII>,cmp> hp;
        hp.push({1,n});
        int ct = 0;
        while(!hp.empty())
        {
            ct ++ ;
            auto t = hp.top();
            hp.pop();
            int l = t.first,r = t.second;
            if((r-l+1)%2 == 1)
            {
                if(l == r)
                {
                    a[l] = ct;
                }
                else
                {
                    int u = (l+r)/2;
                    a[u] = ct;
                    if((u-1) >= l) hp.push({l,u-1});
                    if((u+1) <= r) hp.push({u+1,r});
                }
            }
            else
            {
                int u = (l+r-1)/2;
                a[u] = ct;
                if((u-1) >= l) hp.push({l,u-1});
                if((u+1) <= r) hp.push({u+1,r});
            }
        }
        for (int i = 1 ; i <= n ; i ++ )
        {
            cout << a[i] << " ";
        }
        cout << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/QFNU-ACM/p/12895318.html