打卡信奥刷题(3484)用C++实现信奥题 P10688 Buy Tickets

P10688 Buy Tickets

题目描述

春节期间在中国买火车票很困难,所以我们必须早起并加入长队…… 春节即将来临,但不幸的是,小猫仍然有安排要去各地。现在,他必须乘火车前往四川省绵阳,参加信息学奥林匹克国家队的冬令营选拔。 现在是凌晨一点,外面一片漆黑。来自西北的寒风并没有吓退排队的人群。寒冷的夜晚让小猫打了个寒颤。为什么不找个问题来思考呢?这总比冻死要好! 人们不断插队。由于周围太黑,这种行为即使是排在插队者旁边的人也无法发现。「如果队列中的每个人都被分配了一个整数值,并且给出了所有插队者的信息以及他们插队后的站位,我能否找出队列中人们的最终顺序?」小猫想道。

输入格式

输入包含多个测试用例。每个测试用例由 N+1N + 1N+1 行组成,其中 NNN (1≤N≤2×105)(1 \leq N \leq 2\times 10^5)(1N2×105) 在测试用例的第一行给出。接下来的 NNN 行包含成对的值 PosiPos_iPosiValiVal_iVali,按 iii 的递增顺序排列 (1≤i≤N)(1 \leq i \leq N)(1iN)。对于每个 iiiPosiPos_iPosiValiVal_iVali 的范围和含义如下:

  • Posi∈[0,i−1]Pos_i \in [0, i - 1]Posi[0,i1] — 第 iii 个人来到队列中,并站在队列中第 PosiPos_iPosi 个人的后面。售票处被视为第 000 个人,队列最前面的人被视为第 111 个人。
  • Vali∈[0,32767]Val_i \in [0, 32767]Vali[0,32767] — 第 iii 个人被分配了值 ValiVal_iVali。 测试用例之间没有空行。处理到输入的末尾。

输出格式

对于每个测试用例,输出一行以空格分隔的整数,这些整数是队列中人们按顺序站立的值。

输入输出样例 #1

输入 #1

4
0 77
1 51
1 33
2 69
4 
0 20523
1 19243
1 38900
0 31492

输出 #1

77 33 69 51
31492 20523 38900 19243

说明/提示

(由 ChatGPT 4o 翻译)

C++实现

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, c[N], ans[N], t[N], r[N];
int lowbit(int x) { return x & (-x); }
void add(int x, int d){
    for (; x <= 2e5; x += lowbit(x))
        c[x] += d;
}
int query(int x) {
    int pos = 0, sum = 0;
    for (int j = 18; j >= 0; j--)    {
        if (pos + (1 << j) <= n && sum + c[pos + (1 << j)] <= x)        {
            pos += (1 << j);
            sum += c[pos];
        }
    }
    return pos;
}
int main(){
    while (scanf("%d", &n) != EOF)     {
        for (int i = 1; i <= n; i++)
            add(i, 1);
        for (int i = 1; i <= n; i++)
            scanf("%d%d", &t[i], &r[i]);
        for (int i = n; i >= 1; i--)        {
            int pos = query(t[i]);
            pos += 1; // + 1 找到当前人的位置
            ans[pos] = r[i]; // 记录答案
            add(pos, -1); // 空位 - 1
        }
        for (int i = 1; i <= n; i++)
            printf("%d ", ans[i]);
        printf("\n");
    }
}


在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值