GYM地址:2024吉林省赛

题目顺序按照从易到难排序。

I. The Easiest Problem

题意

数一数

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
void solve() {
    string s = "Scan the QR code to sign in now.";
    ll cnt = 0;
    for (auto c : s) {
        if (c <= 'z' && c >= 'a')cnt++;
    }
    cout << cnt << endl;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _ = 1;
    // cin >> _;cin.get();
    while(_--)
        solve();
 
    return 0;
}

L. Recharge

题意

次获得格能量的机会,次获得格能量的机会,充满一个电池需要格能量,溢出的能量会被浪费,问最多能充满多少电池。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
void solve() {
    ll k, x, y;cin >> k >> x >> y;
    if (k == 1) { cout << x + y << "\n";return; }
    ll ans = 0;
    if (k & 1) {
        ll yi = k / 2;
        if (x <= y / yi) {
            ans += x;
            y -= x * yi;
            x = 0;
            ans += y / (yi + 1);
        }
        else {
            ans += y / yi;
            x -= (y / yi);
            y -= (y / yi) * yi;
            if (y * 2 + x >= k) {
                ans += 1;x -= (k - 2 * y);y = 0;
            }
            ans += x / k;
        }
    }
    else {
        ll tot = x + 2 * y;
        ans = tot / k;
    }
    cout << ans << "\n";
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _ = 1;
    cin >> _;cin.get();
    while(_--)
        solve();
 
    return 0;
}

G. Platform Game

题意

在二维平面中有个平台,每个平台有一个高度,以及一个左端点和右端点。机器人从出发,保持向右前进,如果遇到平台端点则会垂直下落,问机器人最终的落点。

思路

排序题,按照高度从高到低、左端点从小到大排序,遍历平台,如果机器人在平台上则更新机器人的位置。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
struct PLAT {
    ll l, r, y;
    operator<(const PLAT& P)const {
        if (y == P.y)return l < P.l;
        return y > P.y;
    }
};
 
void solve() {
    ll n;cin >> n;
    vector<PLAT>plats;
    for (ll i = 0;i < n;i++) {
        ll l, r, y;cin >> l >> r >> y;
        plats.push_back({ l,r,y });
    }
    sort(plats.begin(), plats.end());
    ll sx, sy;cin >> sx >> sy;
    for (auto p : plats) {
        if (p.l < sx && p.r >= sx && p.y < sy) {
            sy = p.y;
            sx = p.r;
        }
    }
    cout << sx << "\n";
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _ = 1;
    cin >> _;cin.get();
    while(_--)
        solve();
 
    return 0;
}

D. Parallel Lines

题意

二维平面上有条平行线,这些直线上有个点,已知每条直线上至少有个点。现在给出个点,找出这条平行线(用点表示)。

数据范围

思路

注意的范围,最多为,可以枚举来选择平行线的斜率,对于条平行线,当我选择了个点时,这个点中必然至少有两个点之间的斜率是条平行线的斜率。

确定斜率之后,我们分别计算过每个点斜率为的直线在轴上的截距,并计数相同截距的点的数目,注意垂直于轴的情况。

只有同时符产生截距数目恰好为,且每个截距的点数目至少为时,我们才找到了所要的条平行线。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double ld;
 
struct Point {
    ll x, y;
};
 
void solve() {
    ll n, k;cin >> n >> k;
    vector<Point>points(n);
    map<ll, vector<ll>>rx;
    for (ll i = 0;i < n;i++) {
        cin >> points[i].x >> points[i].y;
        rx[points[i].x].push_back(i + 1);
    }
    if (rx.size() == k) {
        bool f = true;
        for (auto i : rx) {
            if (i.second.size() < 2) { f = false;break; }
        }
        if (f) {
            for (auto i : rx) {
                cout << i.second.size() << " ";
                for (auto j : i.second) {
                    cout << j << " ";
                }
                cout << "\n";
            }
            return;
        }
    }
    ll b = 1000000;
    map<ll, bool>mpk;
    for (ll i = 0;i < k + 1;i++) {
        for (ll j = i + 1;j < k + 1;j++) {
            ll px = points[i].x, py = points[i].y, qx = points[j].x, qy = points[j].y;
            if (px == qx) {
                continue;
            }
            ld ki = 1.0 * (py - qy) / (px - qx);
            ll kk = (ll)(ki * b);
            if (mpk.count(kk) == 0)mpk[kk] = true;
        }
    }
    for (auto kk : mpk) {
        ld ki = 1.0 * kk.first / b;
        map<ll, vector<ll>>cnt;
        for (ll i = 0;i < n;i++) {
            ll x = points[i].x, y = points[i].y;
            ld bi = y - ki * x;
            ll bb = (ll)(bi * b);
            cnt[bb].push_back(i + 1);
            if (cnt.size() > k)break;
        }
        if (cnt.size() == k) {
            bool f = true;
            for (auto i : cnt) {
                if (i.second.size() < 2) { f = false;break; }
            }
            if (!f)continue;
            for (auto i : cnt) {
                cout << i.second.size() << " ";
                for (auto j : i.second) {
                    cout << j << " ";
                }
                cout << "\n";
            }
            return;
        }
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _ = 1;
    // cin >> _;cin.get();
    while (_--)
        solve();
 
    return 0;
}

E. Connected Components

题意

个王国,编号从,每个王国有两个属性值,如果两个王国的属性值满足,则这两个王国是相连的。问有多少个连通块。

数据范围

思路