2026年GPLT天梯赛总结

从前到后a了11个题,刚好175铜,说说总结。这是我第一次国奖(以及第一次写博客),祝贺一下,去年也来打了,但是那时候整个人的状态都不好,好像只有6、70分,今年连规则都忘了,但状态不错(可能是我睡到10点才醒缘故?),本来也没打算拿奖,打算打完就走人。但越到后面状态越好,想拼一下,可惜L2差一题,时间来不及了,连样例的图都没画出来(我可能就能看出来可能有环了)。感觉天梯赛的难度主要在题量和L3上,哪怕前面的题简单也来不及做L3,附上我的代码,随便看看吧。

L1

基本没什么好说的

p1

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << "Building the Future, One Line of Code at a Time.";
    return 0;
}

p2

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    cout << n * 15;
    return 0;
}

p3

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int a, b; cin >> a >>b;
    cout << b - a << '\n';
    if(b - a <= 0)cout << "hai sheng ma?";
    else if(b - a <= 250)cout << "nin tai cong ming le!";
    else cout << "jiu ting tu ran de...";
    return 0;
}

p4

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    int ans = 0;
    while(n--){
        int t; cin >> t;
        if(t < 1700)ans++;
    }
    cout << ans;
    return 0;
}

p5

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    set<int> s0, s1;
    for(int i = 0; i < n; i++){
        int no, tmp; cin >> no >> tmp;
        if(tmp == 1){
            if(s0.count(no))s0.erase(no);
            s1.insert(no);
        }else if(tmp == 0 && s1.count(no) == 0){
            s0.insert(no);
        }
    }
    vector<int> ans;
    for(auto i : s0){
        ans.push_back(i);
    }
    if(s0.size() == 0)cout << "NONE";
    else {
        for(int i = 0; i < (int)ans.size(); i++){
            cout << ans[i];
            if(i != (int)ans.size() - 1)cout << ' ';
        }
    }
    return 0;
}

比赛时猪脑过载想不出来怎么遍历set比较方便输出,最后开了个vector复制了一遍,改成下面更好:

bool first = 1;
for (int x : good) {
    if (!first) cout << ' ';
    first = 0;
    cout << x;
}

p6

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vector<int> ans;
    for(int i = 0; i < 11; i++){
        string s; 
        getline(cin, s);
        ans.push_back(s.size());
    }
    for(int i = 0; i< 11; i++){
        cout << ans[i];
    }
    return 0;
}

p7

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    ll mmax = INT_MIN, mmin = INT_MAX, aver = 0;
    vector<ll> num(n);
    for(int i = 0; i < n; i++){
        cin >> num[i];
        aver += num[i];
        mmax = max(num[i], mmax);
        mmin = min(num[i], mmin);
    }
    vector<int> ans;
    aver /= n;
    for(int i = 0; i < n; i++){
        if(num[i] > 2 * aver)ans.push_back(i + 1);
    }
    cout << mmax << ' ' << mmin << ' ' << aver << '\n';
    if(ans.size() == 0)cout << "Normal";
    else {
        for(int i = 0; i < (int)ans.size(); i++){
            cout << ans[i];
            if(i != (int)ans.size() - 1)cout << ' ';
        }
    }
    return 0;
}
# L2
不难只考了基本的算法,反映出我的C++基本功不扎实,字符串等于没练,今年这么简单的字符串题应该很快就能秒的,还有就是一些常见函数的返回值和参数都不知道。

p8

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    for(int i = 0; i < n; i++){
        int opt; cin >> opt;
        if(opt == 1){
            string tmp; cin >> tmp;
            vector<int> vpos;
            size_t pos = 0;
            for(int j = 0; j < 3; j++){
                pos = s.find(tmp, pos);
                if(pos == string::npos)break;
                vpos.push_back(pos);
                pos ++;
            }
            if(vpos.size() == 0)cout << -1 << '\n';
            else {
                for(int j = 0; j < (int)vpos.size(); j++){
                    cout << vpos[j];
                    if(j != (int)vpos.size() - 1)cout << ' ';
                }cout << '\n';
            }
        }
        else if(opt == 2){
            int pos; cin >> pos;
            string tmp; cin >> tmp;
            s.insert(pos, tmp);
            cout << s << '\n';
        }
        else {
            int l, r; cin >> l >> r;
            for(int j = 0; j < (r - l + 1) / 2; j++){
                swap(s[l + j], s[r - j]);
            }
            cout << s << '\n';
        }
    }
    return 0;
}

同样猪脑过载,赛时被find函数究竟返回什么类型憋了很久

p9

没话说了,感觉自己好蠢,真的想不出来更好的方法了

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n, t; cin >> n >> t;
    vector<int> vn(n + 1);
    vector<bool> vis(n + 1);
    vector<int> ans;
    int sum = 0, m = 0;
    for(int i = 1; i <= n; i++){
        cin >> vn[i];
        if(vn[i] <= t){
            ans.push_back(i);
            vis[i] = true;
        }
        else {
            sum += vn[i];
            m++;
        }
    }
    bool f = 1;
    while(ans.size() < n){
        t = sum / m;
        // cout << t << '\n';
        sum = 0;
        m = 0;
        if(!f){
            for(int i = 1; i <= n; i++){
                if(!vis[i]){
                    if(vn[i] <= t){
                        ans.push_back(i);
                        vis[i] = true;
                    }
                    else {
                        sum += vn[i];
                        m++;
                    }
                }
            }
        }
        else {
            for(int i = n; i >= 1; i--){
                if(!vis[i]){
                    if(vn[i] <= t){
                        ans.push_back(i);
                        vis[i] = true;
                    }
                    else {
                        sum += vn[i];
                        m++;
                    }
                }
            }
        }
        f = !f;
    }
    for(int i = 0; i < n; i++){
        cout << ans[i] ;
        if(i != (int)ans.size() - 1)cout << ' ';
    }
    return 0;
}

p10

忘了对于自定义类型究竟怎么使用upper_bound(),最开始重载了三个参数为int的比较运算符,还是报错,想了好长时间,最后手写二分

  • upper_bound()可以给第四个参数传lambda表达式比较自定义类和int
auto it = upper_bound(vi.begin(), vi.end(), tmp,
            [](int val, const num& x) {
                return val < x.data;
            }
        );
  • 也可以重载参数为该类的小于号,upper_bound()第三个参数改为该类
auto it = upper_bound(vi.begin(), vi.end(), num{0, tmp});
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
class num{
    public:
    int no, data;
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    vector<int> pos;
    vector<num> vi(n);
    int mmax = 0;
    for(int i = 0; i < n; i++){
        cin >> vi[i].data;
        vi[i].no = i + 1;
        if(vi[i].data > mmax){
            mmax = vi[i].data;
            pos.clear();
            pos.push_back(i + 1);
        }else if(vi[i].data == mmax)pos.push_back(i + 1);
    }

    for(int i = 0; i < (int)pos.size(); i++){
        cout << pos[i];
        if(i != (int)pos.size() - 1) cout << ' ';
    }cout << '\n';

    int m; cin >> m;
    sort(vi.begin(), vi.end(), [](const num& a, const num& b){
        return tie(a.data, a.no) < tie(b.data, b.no);
    });
    for(int i = 0; i < m; i++){
        int tmp; cin >> tmp;
        int l = 0, r = n - 1;
        while(l < r){
            int mid = (l + r) >> 1;
            if(vi[mid].data > tmp){
                r = mid;
            }else {
                l = mid + 1;
            }
        }
        if(vi[n - 1].data <= tmp)cout << 0 << '\n';
        else cout << vi[l].no << '\n';
    }
    return 0;
}

p11

递归会爆栈,必须改栈

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1000000007;
const int N = 1000005;
vector<pair<int, int>> kid;
int dfs(int idx, map<int, vector<pair<int, int>>>& miv, int res){
    if(miv[idx].size() == 0){
        kid.push_back({idx, res});
        return res;
    }
    int mmax = 0; 
    for(int i = 0; i < (int)miv[idx].size(); i++){
        mmax = max(dfs(miv[idx][i].first, miv, min(res, miv[idx][i].second)), mmax);
    }
    return mmax;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    map<int, vector<pair<int, int>>> miv;
    for(int i = 1; i <= n - 1; i++){
        int f, data; cin >> f >> data;
        // miv[i].push_back({f, data});
        miv[f].push_back({i, data});
    }
    int mmax = 0;
    stack<int> si, sres;
    si.push(0);
    sres.push(INT_MAX);
    while(!si.empty()){
        int idx = si.top();
        int curmax = sres.top();
        si.pop();
        sres.pop();
        if(miv[idx].size() == 0){
            kid.push_back({idx, curmax});
            mmax = max(mmax, curmax);
        }
        else {
            for(int i = 0; i < (int)miv[idx].size(); i++){
                si.push(miv[idx][i].first);
                sres.push(min(curmax, miv[idx][i].second));
            }
        }
    }
    cout << mmax << '\n';
    vector<int> ans;
    for(int i = 0; i < (int)kid.size(); i++){
        if(kid[i].second == mmax)ans.push_back(kid[i].first);
    }
    sort(ans.begin(), ans.end());
    for(int i = 0; i < (int)ans.size(); i++){
        cout << ans[i];
        if(i != (int)ans.size() - 1)cout << ' ';
    }
    return 0;
}

后面的p12因只有20分钟了,没读清题,甚至没看好数据,不知道有环,while死活退不出来,赛后仔细看了数据轻轻的四了...

posted @ 2026-04-18 21:19  Aloutte  阅读(102)  评论(3)    收藏  举报