比赛链接:https://pintia.cn/market/item/1371703238093053952

7-1 打印三角形拼图 (15 分)

题解

找规律。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    char up, down, diag;
    cin >> n >> up >> down >> diag;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i < j) {
                cout << up;
            } else if (i == j) {
                cout << diag;
            } else {
                cout << down;
            }
        }
        cout << "
";
    }
    return 0;
}

7-2 赌马 (20 分)

题解

按照题意排个序就可以了,考虑将 (t_x = frac{s_x}{v_x} < t_y = frac{s_y}{v_y}) 移项得到: (s_x v_y < s_y v_x) ,这样就只剩下整数间的运算,避免了浮点数的误差。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> num(n), s(n), v(n);
    for (int i = 0; i < n; i++) {
        cin >> num[i] >> s[i] >> v[i];
    }
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    sort(p.begin(), p.end(), [&](int x, int y) {
        if (s[x] * v[y] != s[y] * v[x]) {
            return s[x] * v[y] < s[y] * v[x];
        } else {
            return num[x] < num[y];
        }
    });
    for (int i = 0; i < 3; i++) {
        cout << num[p[i]] << " 
"[i == 2];
    }
    return 0;
}

7-3 拼题 A 是真爱 (20 分)

题解

记录字母连续出现的区间,逐一截取判断即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string s;
    getline(cin, s);
    s = ' ' + s + ' ';
    vector<pair<int, int>> seg;
    for (int i = 0; i < int(s.length()); i++) {
        if (isalpha(s[i])) {
            int j = i + 1;
            while (j < int(s.length()) and isalpha(s[j])) {
                ++j;
            }
            seg.emplace_back(i, j - i);
            i = j - 1;
        }
    }
    int cnt = 0;
    for (int i = 0; i < int(seg.size()); i++) {
        string t = s.substr(seg[i].first, seg[i].second);
        if (t == "pintia" or t == "Pintia") {
            ++cnt;
        }
    }
    cout << cnt << "
";
    if (cnt == 0) {
        cout << "wu gan" << "
";
    } else if (cnt <= 3) {
        cout << "you ai" << "
";
    } else {
        cout << "zhen ai la" << "
";
    }
    return 0;
}

7-4 素数等差数列 (20 分)

题解

埃筛出所有素数然后枚举等差数列的前两项即可。

Tips

(10^5) 内有 (9592) 个素数,所以 (O_{(n^2)}) 的算法需要做一些优化。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e5 + 10;
vector<bool> is_prime(N, true);
void Init() {
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i < N; i++) {
        if (not is_prime[i]) {
            continue;
        }
        for (int j = i + i; j < N; j += i) {
            is_prime[j] = false;
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Init();
    int n, maxp;
    cin >> n >> maxp;
    vector<int> prime;
    for (int i = 2; i <= maxp; i++) {
        if (is_prime[i]) {
            prime.push_back(i);
        }
    }
    int a = -1, b = -1;
    for (int i = 0; i < int(prime.size()); i++) {
        for (int j = i + 1; j < int(prime.size()); j++) {
            if ((n - 1) * (prime[j] - prime[i]) > prime.back()) { //优化一
                continue;
            }
            bool ok = true;
            for (int k = 2; k <= n - 1; k++) {
                if (not binary_search(prime.begin(), prime.end(), prime[i] + k * (prime[j] - prime[i]))) {
                    ok = false;
                    break; //优化二
                }
            }
            if (ok and prime[j] - prime[i] >= b - a) {
                a = prime[i];
                b = prime[j];
            }
        }
    }
    if (n == 1 or a == -1) {
        cout << prime.back() << "
";
    } else {
        for (int i = 0; i < n; i++) {
            cout << a + i * (b - a) << " 
"[i == n - 1];
        }
    }
    return 0;
}

7-5 实验室使用排期 (25 分)

题解

挺经典的一道贪心题,将区间按照右端点从小到大排序即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    scanf("%d", &n);
    vector<int> l(n), r(n);
    for (int i = 0; i < n; i++) {
        int h1, m1, s1, h2, m2, s2;
        scanf("%d:%d:%d %d:%d:%d", &h1, &m1, &s1, &h2, &m2, &s2);
        l[i] = h1 * 3600 + m1 * 60 + s1;
        r[i] = h2 * 3600 + m2 * 60 + s2;
    }
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    sort(p.begin(), p.end(), [&](int x, int y) {
        if (r[x] != r[y]) {
            return r[x] < r[y];
        } else {
            return l[x] < l[y];
        }
    });
    int ans = 1;
    for (int i = 0; i < n; ) {
        int j = i + 1;
        while (j < n and l[p[j]] < r[p[i]]) {
            ++j;
        }
        if (j < n) {
            ++ans;
        }
        i = j;
    }
    printf("%d
", ans);
    return 0;
}