SMU 2024 winter round1

7-1 最好的文档

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cout << "Good code is its own best documentation.";
    return 0;
}

7-2 自动编程

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    string s;
    cin >> s;
    cout << "print(" << s << ")\n";
    return 0;
}

7-3 程序员买包子

n , x , m , k = input().split(" ")
if k == n :
    print("mei you mai {} de".format(x))
elif k == m :
    print("kan dao le mai {} de".format(x))
else :
    print("wang le zhao mai {} de".format(x))

7-4 猜数字-交互版

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    int l = 1, r = n, res = -1;
    string s;
    for (int mid; l <= r;) {
        mid = (l + r) / 2;
        cout << mid << endl;
        cin >> s;
        if (s == ">=") res = mid, l = mid + 1;
        else r = mid - 1;
    }
    cout << "! " << res << endl;
    return 0;
}

7-5 斯德哥尔摩火车上的题

def f(a):
    s = ""
    for i in range( 1 , len(a) ):
        if int(a[i]) % 2  == int(a[i-1]) % 2 :
            s += max( a[i] , a[i-1] )
    return s

a = input()
b = input()
a = f(a)
b = f(b)
if a == b :
    print(a)
else :
    print(a)
    print(b)

7-6 剪切粘贴

模拟题

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    string s;
    int n;
    cin >> s >> n;
    int l, r;
    string a, b, x, y, z;
    for (; n; n--) {
        cerr << s << "\n";
        cin >> l >> r >> a >> b, l--, r--;
        cerr << " " << l << " " << r << " " << a << " " << b << "\n";
        for (int i = 0; i < s.size(); i++) {
            if (i < l) x += s[i];
            else if (i <= r) y += s[i];
            else z += s[i];
        }
        cerr << x << " " << y << " " << z << "\n";
        s = x + z, x = "", z = "";
        cerr << s << "\n";
        int p = a.size(), q = b.size();
        for (int i = p; i < s.size(); i++) {
            if (s.substr(i - p, p) != a or s.substr(i, q) != b) continue;

            for (int j = 0; j < i; j++)
                x += s[j];
            for (int j = i; j < s.size(); j++)
                z += s[j];
            cerr << x << " " << y << " " << z << "\n";
            s = x + y + z, x = y = z = "";
            break;
        }
        if (y != "") s = s + y , y = "";
        cerr << s << "\n\n";
    }
    cout << s << "\n";
    return 0;
}

7-7 天梯赛的善良

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    map<int, int> cnt;
    for (int x; n; n--) cin >> x, cnt[x]++;
    cout << cnt.begin()->first << " " << cnt.begin()->second << "\n";
    cout << cnt.rbegin()->first << " " << cnt.rbegin()->second << "\n";
    return 0;
}

7-8 谷歌的招聘

把每个字串截取出来,然后判断质数就行

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";


bool is_prime(int x) {
    if (x < 3) return x == 2;
    for (int i = 2; i * i <= x; i++)
        if (x % i == 0) return false;
    return true;
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    for (int l = 0, r = k - 1, x; r < n; l++, r++) {
        x = 0;
        for (int i = l; i <= r; i++) x = x * 10 + s[i] - '0';
        if (is_prime(x)) {
            cout << setw(k) << setfill('0')<< x << "\n";
            return 0;
        }
    }
    cout << "404\n";
    return 0;
}

7-9 锦标赛

把比赛过程想象成一个满二叉树

第一行全部放在每一对的左侧。

然后开始逐行判断,其实每一个结点都有两个位置可以选择,但是当前节点必须大于左子树或右子树的最大值,所以逐个判断,如果都不满足就是No Solution

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
const ldb eps = 1e-9;
const ldb g = 9.8;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int k;
    cin >> k;
    vi res(1 << k), a, b;

    for (int i = 0; i < res.size(); i += 2)
        cin >> res[i], a.push_back(i + 1), b.push_back(res[i]);
    while (a.size() > 1) {
        vi c, d;
        for (int i = 0, x; i < a.size(); i += 2) {
            cin >> x;
            if (x >= b[i]) res[a[i]] = x, c.push_back(a[i + 1]), d.push_back(max({b[i], b[i + 1], x}));
            else if (x >= b[i + 1]) res[a[i + 1]] = x, c.push_back(a[i]), d.push_back(max({b[i], b[i + 1], x}));
            else cout << "No Solution\n", exit(0);
        }
        a = c, b = d;
    }
    cin >> res[a.back()];
    if (res[a.back()] != *max_element(res.begin(), res.end()))
        cout << "No Solution\n", exit(0);
    for (auto i: res) cout << i << " ";
    return 0;
}


7-10 插松枝

模拟题,认真读题

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m, k;
    cin >> n >> m >> k;
    vi pusher(n), box;
    vector<vi> ans;
    for (auto &i: pusher) cin >> i;
    reverse(pusher.begin(), pusher.end());
    while (!pusher.empty() || !box.empty()) {
        vector<int> cur;
        if (!box.empty()) cur.push_back(box.back()), box.pop_back();
        else cur.push_back(pusher.back()), pusher.pop_back();
        while (cur.size() < k) {
            if (!box.empty() && box.back() <= cur.back())
                cur.push_back(box.back()), box.pop_back();
            else {
                while (!pusher.empty() && pusher.back() > cur.back() && box.size() < m)
                    box.push_back(pusher.back()), pusher.pop_back();
                if (!pusher.empty() && pusher.back() <= cur.back())
                    cur.push_back(pusher.back()), pusher.pop_back();
                else break;
            }
        }
        ans.push_back(cur);
    }
    for (const auto &it: ans) {
        cout << it.front();
        for (int i = 1; i < it.size(); i++)
            cout << " " << it[i];
        cout << "\n";
    }
    return 0;
}

7-11 拯救007

特判起点终点,然后宽搜索即可。

但是说直径15,所以起点应该是到原点距离小于\(k+7.5\)的点,但是亲测数据是\(k+15\),所以鉴定为垃圾题

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using pii = pair<int, int>;
using ldb = long double;

const int mod = 998244353;
const ldb eps = 1e-9;
const ldb g = 9.8;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, k;
    cin >> n >> k;
    vector<pii> node;
    vi ed, vis(n);
    queue<int> q;
    for (int i = 0, d = (15 + k) * (15 + k) , x , y; i < n ; i ++ ) {
        cin >> x >> y;
        node.emplace_back( x,  y);
        if (abs(x - 50) <= k) ed.push_back(i);
        else if (abs(x + 50) <= k) ed.push_back(i);
        else if (abs(y - 50) <= k) ed.push_back(i);
        else if (abs(y + 50) <= k) ed.push_back(i);
        if (x * x + y * y <= d) q.push(i);
    }

    for (int x, d = k * k; not q.empty();) {
        x = q.front();
        q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for (int y = 0; y < n; y++) {
            if (vis[y]) continue;
            if ((node[x].first - node[y].first) * (node[x].first - node[y].first) +
                (node[x].second - node[y].second) * (node[x].second - node[y].second) <= d)
                q.push(y);
        }
    }
    for( auto i : ed )
        if( vis[i] ) cout << "Yes\n" , exit(0);
    cout << "No\n";
    return 0;
}


7-12 寻宝图

直接进行暴搜就行,在搜索过程中判断有没有经过宝藏

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using pii = pair<int, int>;
using ldb = long double;

#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

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;

    vector<string> g(n);
    for (auto &i: g) cin >> i;
    int res = 0, ans = 0;
    auto vis = vector(n, vi(m));
    for (int sx = 0, flag; sx < n; sx++)
        for (int sy = 0; sy < m; sy++) {
            if (vis[sx][sy] or g[sx][sy] == '0') continue;
            res++, flag = 0;
            queue<pii> q;
            q.emplace(sx, sy);
            while (not q.empty()) {
                auto [x, y] = q.front();
                q.pop();
                if (vis[x][y]) continue;
                vis[x][y] = 1;
                if (g[x][y] != '1') flag = 1;
                for (int i = 0, fx, fy; i < 4; i++) {
                    fx = x + dx[i], fy = y + dy[i];
                    if (fx < 0 or fy < 0 or fx >= n or fy >= m) continue;
                    if (vis[fx][fy] or g[fx][fy] == '0') continue;

                    q.emplace(fx, fy);
                }
            }
            ans += flag;
        }
    cout << res << " " << ans << "\n";
    return 0;
}

7-13 垃圾箱分布

从每个垃圾箱开始做一次最短路,然后按照题目要求求出最优解

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using pii = pair<int, int>;
using ldb = long double;

#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";

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

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m, k, ds;
    cin >> n >> m >> k >> ds;
    vector <vector<pii>> e(n + m + 1);
    string us, vs;
    for (int u, v, w; k; k--) {
        cin >> us >> vs >> w;
        if (us[0] == 'G') u = n + atoi(us.substr(1).c_str());
        else u = atoi(us.c_str());
        if (vs[0] == 'G') v = n + atoi(vs.substr(1).c_str());
        else v = atoi(vs.c_str());
        e[u].emplace_back(v, w), e[v].emplace_back(u, w);
    }
    auto dij = [e, n, m](int s) -> vi {
        vi dis(n + m + 1, inf), vis(n + m + 1);
        priority_queue<pii, vector<pii>, greater<pii>> q;
        dis[s] = 0, q.emplace(0, s);
        while (not q.empty()) {
            auto [d, x] = q.top();
            q.pop();
            if (vis[x]) continue;
            vis[x] = 1;
            for (auto [y, w]: e[x]) {
                if (vis[y] or dis[y] <= d + w) continue;
                dis[y] = d + w;
                q.emplace(dis[y], y);
            }
        }

        return dis;
    };
    int res = -1, resMin = 0, resSum = inf;
    for (int i = 1, ansMin, ansSum; i <= m; i++) {
        auto dis = dij(n + i);
        ansMin = inf, ansSum = 0;
        for (int j = 1; j <= n; j++) {
            if (dis[j] > ds) ansMin = -1, ansSum = inf;
            ansMin = min(ansMin, dis[j]), ansSum += dis[j];
        }
        if (ansMin > resMin) res = i, resMin = ansMin, resSum = ansSum;
        else if (ansMin == resMin and ansSum < resSum)res = i, resMin = ansMin, resSum = ansSum;
    }
    if (res == -1) cout << "No Solution\n";
    else cout << "G" << res << "\n" << fixed << setprecision(1) << (ldb)resMin << " " << (ldb) resSum / n << "\n";
    return 0;
}


7-14 非常弹的球

高中物理,斜上抛运动,初速度一定是45度角水平移动距离最远。

在起始位置做正交分解

\[m = \frac{w}{1000} \\ E_x=E_y=\frac E 2\\ E_x=\frac 12 m v_x^2 \rightarrow v_x = \sqrt{\frac{E}{m}}\\ t = \frac {E_y}{g}\\ x = v_xt \]

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;

const int mod = 998244353;
const ldb eps = 1e-9;
const ldb g = 9.8;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    ldb m, p;
    cin >> m >> p, m /= 100.0, p = (100.0 - p) / 100.0;
    ldb E = 1000;
    ldb v, t, res = 0;
    while (E > eps) {
        v = sqrt(E / m), t = v / g * 2;
        res += v * t, E = E * p;
    }
    cout << fixed << setprecision(3) << res << "\n";
    return 0;
}

7-15 拯救007(升级版)

这里还是利用bfs,然后顺便统计下距离和路径就好

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;
using i32 = int32_t;
using pii = pair<int, int>;
using ldb = long double;

const int mod = 998244353;
const ldb eps = 1e-9;
const ldb g = 9.8;
const int inf = 1e9;
#define DEBUG(x) cerr <<(#x) << " = " << x  << "\n";
int n, k;

struct Node {
    ldb x, y;

    Node(ldb x = 0, ldb y = 0) : x(x), y(y) {};
} o;

vector<Node> nodes;

ldb dis(Node a, Node b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

ldb dis(int a, int b) {
    return dis(nodes[a], nodes[b]);
}

ldb dis(Node a, int b) {
    return dis(a, nodes[b]);
}

ostream &operator<<(ostream &os, Node x) {
    return os << x.x << " " << x.y;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);

    cin >> n >> k;
    if (k + 7.5 >= 50) {
        cout << "1\n";
        return 0;
    }
    vi ed, d(n, inf), fa(n, -1), vis(n);
    queue<int> q;
    for (int i = 0, x, y; i < n; i++) {
        cin >> x >> y, nodes.emplace_back(x, y);
        if (max(abs(x), abs(y)) + k >= 50) ed.push_back(i);
        if (dis(o, i) <= 7.5 + k) d[i] = 1, q.push(i);
    }
    for (int x; not q.empty();) {
        x = q.front(), q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for (int y = 0; y < n; y++) {
            if (vis[y] or d[y] <= d[x] + 1) continue;
            if (dis(x, y) > k) continue;
            d[y] = d[x] + 1, fa[y] = x, q.push(y);
        }
    }
    int res = inf;
    vi resPath;
    for (auto i: ed) {
        if (d[i] > res or d[i] == inf) continue;
        vi path;
        for (int x = i; x != -1; x = fa[x]) path.push_back(x);
        reverse(path.begin(), path.end());
        if (d[i] < res) res = d[i], resPath = path;
        else if (dis(o, path[0]) < dis(o, resPath[0])) resPath = path;
    }
    if (res == inf) cout << "0\n", exit(0);
    cout << res + 1 << "\n";
    for (auto i: resPath) cout << nodes[i] << "\n";
    return 0;
}
posted @ 2024-01-26 18:15  PHarr  阅读(6)  评论(0编辑  收藏  举报