20240319天梯赛训练

P2669 [NOIP2015 普及组] 金币

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int k , res = 0;
    cin >> k;
    for (int i = 1; k; i++) {
        for (int j = i; j and k; j-- , k --)
            res += i;
    }
    cout << res << "\n";
    return 0;
}

P5660 [CSP-J2019] 数字游戏

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    string s;
    cin >> s;
    int res = 0;
    for( auto i : s )
        res += (i == '1');
    cout << res << "\n";
}

P5015 [NOIP2018 普及组] 标题统计

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    string s;
    int res = 0;
    while (cin >> s)
        res += s.size();
    cout << res << "\n";
}

P5681 [CSP-J2019 江西] 面积

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a , b , c;
    cin >> a >> b >> c;
    if( a * a > b * c ) cout << "Alice\n";
    else cout << "Bob\n";
}

P1190 [NOIP2010 普及组] 接水问题

优先队列模拟

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    priority_queue<int, vi, greater<int>> q;
    for (int i = 1; i <= m; i++) q.push(0);
    for (int i = 1, x; i <= n; i++)
        cin >> x, x += q.top(), q.pop(), q.push(x);
    for (int i = 1; i < m; i++) q.pop();
    cout << q.top() << "\n";
    return 0;
}

P7071 [CSP-J2020] 优秀的拆分

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ui64 = uint64_t;
using i128 = __int128;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

bool cmp(const array<int, 3> &x, const array<int, 3> &y) {
    if (x[0] != y[0]) return x[0] > y[0];
    return x[2] < y[2];
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    if( n & 1 ){
        cout << "-1";
        return 0;
    }
    vi res ;
    for( int i = 1 ; n ; n >>= 1 , i <<= 1)
        if( n & 1 ) res.push_back(i);
    reverse(res.begin(), res.end());
    for( auto i : res )
        cout << i << " ";
    return 0;
}

P2670 [NOIP2015 普及组] 扫雷游戏

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ui64 = uint64_t;
using i128 = __int128;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1, 1, 1, -1, -1}, dy = {1, -1, 0, 0, 1, -1, 1, -1};

bool cmp(const array<int, 3> &x, const array<int, 3> &y) {
    if (x[0] != y[0]) return x[0] > y[0];
    return x[2] < y[2];
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    for (auto &i: g) cin >> i;
    for (int i = 0, cnt; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (g[i][j] == '*') {
                cout << '*';
            } else {
                cnt = 0;
                for (int l = 0, fx, fy; l < 8; l++) {
                    fx = i + dx[l], fy = j + dy[l];
                    if (fx < 0 or fy < 0 or fx >= n or fy >= m) continue;
                    cnt += g[fx][fy] == '*';
                }
                cout << cnt;
            }
        }
        cout << "\n";
    }
    return 0;
}

P1098 [NOIP2007 提高组] 字符串的展开

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ui64 = uint64_t;
using i128 = __int128;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1, 1, 1, -1, -1}, dy = {1, -1, 0, 0, 1, -1, 1, -1};

bool cmp(const array<int, 3> &x, const array<int, 3> &y) {
    if (x[0] != y[0]) return x[0] > y[0];
    return x[2] < y[2];
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b, c;
    cin >> a >> b >> c;
    string s, t;
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] != '-') cout << s[i];
        else {
            auto l = s[i - 1], r = s[i + 1];
            if ('0' <= l and l <= '9' and '0' <= r and r <= '9') {
                if (l >= r) {
                    cout << '-';
                    continue;
                }
                t = "";
                for (l++; l < r; l++) {
                    for (int j = 0; j < b; j++) {
                        if (a <= 2) t += l;
                        else t += '*';
                    }
                }
                if (c == 2) reverse(t.begin(), t.end());
                cout << t;
            } else if ('a' <= l and l <= 'z' and 'a' <= r and r <= 'z') {
                if (l >= r) {
                    cout << '-';
                    continue;
                }
                t = "";
                for (l++; l < r; l++) {
                    for (int j = 0; j < b; j++) {
                        if (a == 1) t += l;
                        else if (a == 2) t += l + 'A' - 'a';
                        else t += '*';
                    }
                }
                if (c == 2) reverse(t.begin(), t.end());
                cout << t;
            } else {
                cout << "-";
            }

        }
    }
    return 0;
}

P5657 [CSP-S2019] 格雷码

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ui64 = uint64_t;
using i128 = __int128;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i128 read() {
    i128 x = 0, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x;
}

string solve(i128 n, i128 k) {
    if (n == 1) {
        if (k == 1) return "1";
        else return "0";
    }
    if (k < ((i128) (1) << (n - 1))) return "0" + solve(n - 1, k);
    return "1" + solve(n - 1, ((i128) (1) << n) - 1 - k);
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    i128 n = read(), k = read();
    cout << solve(n, k) << "\n";
    return 0;
}

P1309 [NOIP2011 普及组] 瑞士轮

每次把赢得人放在一个队列,输的人放在一个队列,就依旧可以保证两个序列有序,然后归并一下,复杂度\(O(RN)\)

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

bool cmp(const array<int, 3> &x, const array<int, 3> &y) {
    if (x[0] != y[0]) return x[0] > y[0];
    return x[2] < y[2];
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, r, q;
    cin >> n >> r >> q, n *= 2, q--;

    vector<array<int, 3>> a(n), b(n / 2), c(n / 2);
    for (int i = 0; i < n; i++)
        cin >> a[i][0], a[i][2] = i + 1;
    for (int i = 0; i < n; i++)
        cin >> a[i][1];
    sort(a.begin(), a.end(), cmp);
    while (r-- > 0) {
        for (int i = 0; i < n; i += 2) {
            if (a[i][1] > a[i + 1][1])
                a[i][0]++, b[i / 2] = a[i], c[i / 2] = a[i + 1];
            else
                a[i + 1][0]++, b[i / 2] = a[i + 1], c[i / 2] = a[i];
        }
        merge(b.begin(), b.end(), c.begin(), c.end(), a.begin(), cmp);
    }
    cout << a[q][2] << "\n";
    return 0;
}

P2058 [NOIP2016 普及组] 海港

可以用双指针维护出长时间\(m\)的时间段,开个桶统计一下。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;
const int inf = 1e18;

const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

const int N = 1e5 + 5, T = 86400;
int cnt[N], res, t[N];
vi x[N];


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    for (int i = 1, l = 1, k; i <= n; i++) {
        cin >> t[i] >> k;
        x[i].resize(k);
        for (auto &xi: x[i]) {
            cin >> xi, cnt[xi]++;
            if (cnt[xi] == 1) res++;
        }
        while (t[i] - t[l] >= T) {
            for (auto &xl: x[l]) {
                cnt[xl]--;
                if (cnt[xl] == 0) res--;
            }
            l++;
        }
        cout << res << "\n";
    }
    return 0;
}

P3952 [NOIP2017 提高组] 时间复杂度

这题其实是个比较简单的模拟题。

为了便于处理,在检查的过程中如果发现ERR就会直接结束运行,所以要先把一组全部的读入都读进来。

首先这个循环的嵌套,我们要用栈来模拟。

首先考虑怎样会ERR

  1. 变量名重复
  2. E或少E

对于1,我用了一个set<string>used表示当前栈中的变量,每次有一个新循环,就把变量插进去,如果插不进去就是ERR

对于2,只要判断过程中栈空和结束后栈不空即可。

下面考虑计算复杂度。

对于每种循环,我规定了三种状态,1对复杂度有贡献,0对复杂度无贡献,-1无法执行,且无法执行的循环子循环全部无法执行。

那么只要在过程中判断每一种循环的状态即可,遇到1入栈就给当前累计复杂度加一,出栈就减一。

考虑如何判断一个循环的父循环是否可以运行?我维护了变量ok表示父循环是否可以运行,只要ok==false强制为-1即可。

当然一种情况是,随着E使得循环出栈,父循环的状态变为可以运行,这个该如何判断?根据我上述定义的规则,如果栈中有-1,一定是在栈顶有若干个连续的-1。所以每次出栈后,判断栈顶不是-1,将ok更新为true即可。

对于复杂度的详细判断可以仔细阅读题目和代码注释。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;


void solve() {
    int n;
    string ans;
    cin >> n >> ans;
    vector<vector<string>> op(n);
    for (string OP, I, X, Y; auto &it: op) {
        cin >> OP;
        if (OP == "F") {
            cin >> I >> X >> Y;
            it = {OP, I, X, Y};
        } else it = {OP};
    }

    set<string> used;
    int cnt = 0, res = 0;
    stack<pair<string, int>> stk;

    for (bool ok = true; auto it: op) { // ok 父循环是否可以运行
        if (it.size() == 1) {
            if (stk.empty()) { // 多 E
                cout << "ERR\n";
                return;
            }
            used.erase(stk.top().first);
            if (stk.top().second == 1) cnt--;
            stk.pop();
            if (stk.empty() or stk.top().second != -1) ok = true; // 父循环可以运行了
        } else {
            auto I = it[1], X = it[2], Y = it[3];
            if (I == "n" or used.insert(I).second == false) {
                cout << "ERR\n";
                return;
            }
            if (X != "n" and Y == "n") { // x -> n 如果可以运行 复杂度++
                if (ok) { // 父循环可以运行
                    stk.emplace(I, 1), cnt++;
                } else { // 父循环不可以运行
                    stk.emplace(I, -1);
                }
            } else if (X == "n" and Y != "n") { // n -> x 子循环全部不能运行
                ok = false, stk.emplace(I, -1);
            } else if (X == "n" and Y == "n") { // n -> n 即使运行 复杂度不变
                stk.emplace(I, vector{-1, 0}[ok]);
            } else { // x -> y 即使运行 复杂度不变
                if (stoi(X) > stoi(Y)) { // x > y 子循环全部不能运行
                    ok = false, stk.emplace(I, -1);
                } else {
                    stk.emplace(I, vector{-1, 0}[ok]);
                }
            }
        }
        res = max(res, cnt);
    }
    if (not stk.empty()) { // 缺 E
        cout << "ERR\n";
        return;
    }
    if (res == 0 and ans == "O(1)")
        cout << "Yes\n";
    else if (res != 0 and ans == "O(n^" + to_string(res) + ")")
        cout << "Yes\n";
    else
        cout << "No\n";
    return;
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--) solve();
    return 0;
}
posted @ 2024-03-19 23:11  PHarr  阅读(7)  评论(0编辑  收藏  举报