Cocoicobird
热爱永远可以成为你继续下去的理由

牛客刷题-Day26

今日刷题:\(F-J\)

G 小C的记事本

QQ_1767711368918

解题思路

模拟、栈:用栈来存储每次变化的字符串,栈顶即为最新的字符串状态。

C++ 代码
#include <bits/stdc++.h>
using namespace std;

int q;

int main() {
    ios::sync_with_stdio(false);
    while (cin >> q) {
        stack<string> stk;
        string str;
        int k;
        int t;
        while (q--) {
            cin >> t;
            if (t == 1) {
                cin >> str;
                if (stk.empty())
                    stk.push(str);
                else
                    stk.push(stk.top() + str);
            } else if (t == 2) {
                cin >> k;
                string tmp(stk.top().begin(), stk.top().end() - k);
                stk.push(tmp);
            } else if (t == 3) {
                cin >> k;
                cout << stk.top()[k - 1] << endl;
            } else {
                stk.pop();
            }
        }
    }
    return 0;
}

H Keep In Line

QQ_1767711573364

解题思路

模拟、队列:当 opt=in,则入队,标记该 name=1;否则出队,标记 name=0,若队首为 name,则是正常出队,否则将插队的出队。

C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;

int T, n;

void solve() {
    map<string, int> st;
    queue<string> que;
    cin >> n;
    int res = 0;
    for (int i = 0; i < n; i++) {
        string opt, name;
        cin >> opt >> name;
        if (opt == "in") {
            st[name] = 1;
            que.push(name);
        } else {
            st[name] = 0;
            if (name == que.front())
                res++;
            while (!que.empty() && !st[que.front()])
                que.pop();
        }
    }
    cout << res << endl;
}

int main() {
    cin >> T;
    while (T--)
        solve();
    return 0;
}

J [NOIP2016]蚯蚓

QQ_1767711807502

解题思路

参考:P2827 NOIP2016 提高组 蚯蚓
首先最直接的想法 \(O(mlogm)\):每次取最长的蚯蚓 \(x\),新产生两只蚯蚓的长度为 \(\lfloor{px}\rfloor\)\(x-\lfloor{px}\rfloor\),然后其余蚯蚓长度 \(+q\),则等价于新产生的蚯蚓长度 \(-q\)
那么在 \([t,t+1)\) 时(\(t\in Z \bigcap t\in[0,n)\)),蚯蚓真实长度为 \(x+qt\),然后在此基础上新产生两只蚯蚓。即:

  1. 取最长的蚯蚓 \(x'\),真实长度为 \(x=x'+qt\)
  2. 划分:\(\lfloor{px}\rfloor\)\(x-\lfloor{px}\rfloor\)
  3. 新产生蚯蚓:\(\lfloor{px}\rfloor-q-qt\)\(x-\lfloor{px}\rfloor-q-qt\)

最终输出时全局偏移量为 \(mt\)

优化:首先考虑 \(q=0\),即不会增长。每次取最长的蚯蚓 \(x\),新产生两只蚯蚓的长度为 \(\lfloor{px}\rfloor\)\(x-\lfloor{px}\rfloor\)。假设 \(x_1\ge x_2\),则显然有 \(\lfloor{px_1}\rfloor\ge\lfloor{px_2}\rfloor\),那么是否 \(x_1-\lfloor{px_1}\rfloor\ge x_2-\lfloor{px_2}\rfloor\)

证明:\(x_1-x_2\in Z\)\(x_1-x_2\ge p(x_1-x_2)\)\(x_1-x_2+px_2\ge px_1\)\(\lfloor x_1-x_2+px_2\rfloor\ge\lfloor px_1\rfloor\)\(\lfloor px_2\rfloor+x_1-x_2\ge\lfloor px_1\rfloor\)\(x_1-\lfloor{px_1}\rfloor\ge x_2-\lfloor{px_2}\rfloor\)

考虑 \(q>0\)。假设某一秒,切开 \(x_1\),下一秒,切开 \(x_2+q\)\(x_2+q\) 在上一秒时为 \(x_2\),因此 \(x_1≥x_2\)。证明目标是 \(⌊px_1⌋+q≥⌊p(x_2+q)⌋\)\(x_1−⌊px_1⌋+q≥x_2+q−⌊p(x_2+q)⌋\)

对于 \(⌊px_1⌋+q≥⌊p(x_2+q)⌋\)\(⌊px_1⌋+q=⌊px_1+q⌋\ge⌊px_2+q⌋\ge⌊px_2+pq⌋\ge⌊p(x_2+q)⌋\)
对于 \(x_1−⌊px_1⌋+q≥x_2+q−⌊p(x_2+q)⌋\)\(x_1−⌊px_1⌋+q≥x_2−⌊px_2⌋+q\ge x_2−⌊px_2+pq⌋+q\ge x_2−⌊p(x_2+q)⌋+q\)

C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, MIN = -1e9;
typedef pair<int, int> PII;

int n, m, q, u, v, t;
int a[N];
queue<int> que[3];

int main() {
    scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    sort(a + 1, a + n + 1);
    for (int i = n; i; i--)
        que[0].push(a[i]);
    for (int i = 0; i < m; i++) {
        PII p = max({make_pair(que[0].empty() ? MIN : que[0].front(), 0), 
                     make_pair(que[1].empty() ? MIN : que[1].front(), 1),
                     make_pair(que[2].empty() ? MIN : que[2].front(), 2)});
        int x = p.first + q * i, j = p.second;
        que[j].pop();
        int b = 1ll * x * u / v, c = x - b;
        que[1].push(b - q - q * i);
        que[2].push(c - q - q * i);
        if (i % t == t - 1)
            printf("%d ", x);
    }
    printf("\n");
    for (int i = 1; i <= n + m; i++) {
        PII p = max({make_pair(que[0].empty() ? MIN : que[0].front(), 0), 
                     make_pair(que[1].empty() ? MIN : que[1].front(), 1),
                     make_pair(que[2].empty() ? MIN : que[2].front(), 2)});
        int x = p.first, j = p.second;
        que[j].pop();
        if (i % t == 0)
            printf("%d ", x + q * m);
    }
    printf("\n");
    return 0;
}
posted on 2026-01-07 10:50  Cocoicobird  阅读(6)  评论(0)    收藏  举报