STL/set Codeforces Round #710 (Div. 3) E题

博客详细解析了Codeforces编程竞赛中的一道题目,涉及到从给定的数组q反推原数组a的过程,并给出了构造最小和最大字典序原数组的算法。通过设置集合并根据q[i]的值动态更新原数组元素,确保在满足条件的情况下得到最小和最大字典序的解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL/set Codeforces Round #710 (Div. 3) E题

题意:
给一数组q,求原数组a,给定的数组的第i位表示原数组1到i的最大值。
输出可能的原数组的最小字典序和最大字典序

解析:
如果q[i] = q[i-1],代表新的数字不大于所有前面出现过的数字
如果q[i] > q[i-1],代表新的数字更新了最大值,a[i] = q[i]
如果q[i] < q[i-1] ? 这不存在,因为q[i]代表从1到 i 的最大值

策略- 先将所有确定的a[i]都定好,将未确定的数加入set里,
从前往后遍历,
如果是要生成最小的字典序,则每次取set.begin()
如果要生成最大的字典序,利用set.lower_bound(x)找到大于等于当前的数的位置,然后–,往前退一步,就是小于当前数的最大值。

int t,n,m;
int a[N];
void cul(vector<int> &q, bool flag){
    set<int> se;
    for(int i=1;i<=q.size();i++) se.insert(i);
    for(int i=0;i<q.size();i++)
        if(q[i] != -1) se.erase(q[i]);
    int last = -1;
    for(int i=0;i<q.size();i++){
        set<int> :: iterator it;
        if(q[i] == -1){
            if(flag){
                it = se.begin();
            }else{
                it = --se.lower_bound(last);
            }
            q[i] = *it;
            se.erase(*it);
        }else{
            last = q[i];
        }
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        vector<int> res1(n,-1),res2(n,-1);
        int last = -1;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            if(a[i] != last){
                res1[i] = a[i];
                res2[i] = a[i];
                last = a[i];
            }
        }
        cul(res1,true);
        cul(res2,false);
        for(int t : res1) printf("%d ",t);
        puts("");
        for(int t : res2) printf("%d ",t);
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值