Blue-Red Permutation 贪心,思维

在这里插入图片描述
题意 :

  • 给一序列以及序列对应每个位置的颜色,R颜色对应可以增加若干,B反之,问是否能将序列变化为1-n所有数有且仅有1个

思路 :

  • 每个数可以得到一个变化范围区间,那么得到了n个区间,区间只存左右端点,将区间按照第一优先l第二优先r进行升序排序,然后从1枚举到n看是否都能被取到,若是则yes,反之no
  • 要考虑无效区间,l和r赋值时特殊标记以及判断是否合法时特殊判断即可
  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn) S u m Sum Sum o f of of n < = 2 5 n<=2^5 n<=25
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 2e5 + 10;

struct rec
{
    
    
    int l, r;

    rec(int a = 0, int b = 0)
    {
    
    
        l = a, r = b;
    }
}r[N];

int n;
int a[N];
char col[N];

inline bool check()
{
    
    
    for (int i = 1; i <= n; i ++ )
    {
    
    
        if (r[i].l > r[i].r) return false;
        if (i < r[i].l) return false;
        if (i > r[i].r) return false;
    }
    return true;
}

int main()
{
    
    
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

    int _;
    cin >> _;

    while (_ -- )
    {
    
    
        cin >> n;
        for (int i = 1; i <= n; i ++ ) cin >> a[i];
        for (int i = 1; i <= n; i ++ ) cin >> col[i];

        for (int i = 1; i <= n; i ++ )
        {
    
    
            if (col[i] == 'B')
            {
    
    
                r[i] = rec(1, a[i]);
                if (a[i] < 1) r[i] = rec(1, 0);
                if (a[i] > n) r[i] = rec(1, n);
            }
            else
            {
    
    
                r[i] = rec(a[i], n);
                if (a[i] < 1) r[i] = rec(1, n);
                if (a[i] > n) r[i] = rec(n + 1, n);
            }
        }

        sort(r + 1, r + n + 1, [&](rec a, rec b){
    
    return a.l == b.l ? a.r < b.r : a.l < b.l;});

        if (check()) cout << "YES" << endl;
        else cout << "NO" << endl;
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/m0_51448653/article/details/121199624