西南民族大学 春季 2023 训练赛 7

发布时间 2023-04-15 16:58:46作者: PHarr

L1-1 人与神

To iterate is human, to recurse divine.

L1-2 两小时学完C语言

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    cout << max(0, n - m * k);
    return 0;
}

L1-3 强迫症

#include <bits/stdc++.h>

using namespace std;

int main() {
    string s;
    cin >> s;
    if (s.size() == 6) {
        cout << s.substr(0, 4) << "-" << s.substr(4, 2);
    } else {
        int t = (s[0] - '0') * 10 + s[1] - '0';
        if (t < 22) cout << 20;
        else cout << 19;
        cout << s[0] << s[1] << "-" << s[2] << s[3];
    }
    return 0;
}

L1-4 降价提醒机器人

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    double m;
    cin >> n >> m;
    for (double x; n; n--) {
        cin >> x;
        if (m > x) printf("On Sale! %.1lf\n", x);
    }
}

L1-5 大笨钟的心情

#include <bits/stdc++.h>
using namespace std;

int main(){
	vector<int> a(24);
	for( auto &i : a ) cin >> i;
	for( int x ; true; ){
		cin >> x;
		if( x < 0 || x > 23 ) break;
		cout << a[x];
		if( a[x] > 50 ) cout << " Yes\n";
		else cout << " No\n";
	}
}

L1-6 吉老师的回归

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    if (n == m) {
        cout << "Wo AK le\n";
        return 0;
    }
    getchar();
    for (int i = 1; i <= n; i++) {
        string s;
        getline(cin, s);

        if (s.find("easy") == -1 && s.find("qiandao") == -1) {
            if (m > 0) m--;
            else {
                cout << s << "\n";
                return 0;
            }
        }
    }
    cout << "Wo AK le\n";
    return 0;
}

L1-7 天梯赛的善良

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    int a = 0, b = 0, c = INT_MAX, d = INT_MIN;

    cin >> n;
    for (int x; n; n--) {
        cin >> x;
        if (x < c) c = x, a = 1;
        else if (x == c) a++;

        if (x > d) d = x, b = 1;
        else if (x == d) b++;
    }
    cout << c << " " << a << "\n" << d << " " << b << "\n";
    return 0;
}

L1-8 乘法口诀数列

#include <bits/stdc++.h>
using namespace std;

int main(){
	int a , b , n ;
	cin >> a >> b >> n;
	vector<int> v(2);
	v[0] = a , v[1] = b;
	for( int i = 2 , x ; i < n ; i ++ ){
		x = v[i-1] * v[i-2];
		if( x > 9 ) v.push_back(x / 10) , v.push_back(x % 10);
		else v.push_back(x);
	}
	for( int i = 0 ; i < n ; i ++ )
		cout << v[i] << " \n"[i == n-1 ];
	return 0;
}

L2-1 包装机

小模拟,用栈模拟一下筐就好了。注意对筐的操作前一定要先检查筐的状态。

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, m, s;
    cin >> n >> m >> s;
    vector<int> pos(n + 1, 0);
    vector<string> t(n + 1);
    stack<char> box;
    string ans;

    for (int i = 1; i <= n; i++)
        cin >> t[i];
    for (int x;;) {
        cin >> x;
        if (x == -1) break;
        else if (x == 0) {
            if (!box.empty()) ans += box.top(), box.pop();
        } else {
            if (pos[x] == m) continue;
            if (box.size() == s) ans += box.top(), box.pop();
            box.push(t[x][pos[x]]), pos[x]++;
        }
    }
    cout << ans << "\n";
    return 0;
}

L2-2 病毒溯源

从所有的叶子简单,方向还原出序列后,统计最长且最小的即可

#include <bits/stdc++.h>

using namespace std;

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

int main() {
    int n = read();
    vector<int> cur, ans, fa(n, -1), d(n, 0);
    for (int i = 0, k, x; i < n; i++) {
        d[i] = k = read();
        for (; k; k--)
            x = read(), fa[x] = i;
    }
    for (int i = 0, t; i < n; i++) {
        if (d[i]) continue;
        cur.clear();
        t = i;
        while (t != -1) cur.push_back(t), t = fa[t];

        reverse(cur.begin(), cur.end());

        if (cur.size() > ans.size()) ans = cur;
        else if (cur.size() == ans.size() && cur < ans) ans = cur;
    }
    cout << ans.size() << "\n";
    for (auto i: ans)
        cout << i << " \n"[i == ans.back()];

    return 0;
}

L2-3 清点代码库

用 map统计没种出现的次数。然后对所有的种类进行排序

#include <bits/stdc++.h>

using namespace std;

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

int main() {
    int n = read();
    vector<int> cur, ans, fa(n, -1), d(n, 0);
    for (int i = 0, k, x; i < n; i++) {
        d[i] = k = read();
        for (; k; k--)
            x = read(), fa[x] = i;
    }
    for (int i = 0, t; i < n; i++) {
        if (d[i]) continue;
        cur.clear();
        t = i;
        while (t != -1) cur.push_back(t), t = fa[t];

        reverse(cur.begin(), cur.end());

        if (cur.size() > ans.size()) ans = cur;
        else if (cur.size() == ans.size() && cur < ans) ans = cur;
    }
    cout << ans.size() << "\n";
    for (auto i: ans)
        cout << i << " \n"[i == ans.back()];

    return 0;
}

L2-4 哲哲打游戏

建图然后模拟一下即可

#include <bits/stdc++.h>

using namespace std;

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

int main() {
    int n = read(), m = read();
    vector<vector<int>> e(n + 1);
    for (int i = 1, k; i <= n; i++) {
        k = read(), e[i] = vector<int>(k);
        for (auto &j: e[i]) j = read();
    }
    vector<int> p(105);
    int now = 1;
    for (int op, x; m; m--) {
        op = read(), x = read();
        if (op == 0) now = e[now][x - 1];
        else if (op == 1) cout << now << "\n", p[x] = now;
        else now = p[x];
    }
    cout << now << "\n";
    return 0;
}

L3-1 森森旅游

正向建图以现金为代价,反向建图以旅游金为代价。分别从起点和终点两边 dij 统计最小花费,然后枚举兑换旅游金的点统计出全局最优解。

对于修改汇率,用multiset维护说有点兑换的代价,每次删掉就插入新的,begin()就是每次修改后的答案。

#include <bits/stdc++.h>

using namespace std;

#define int long long

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

const int INF = 1e18;

int n, m, p;

typedef pair<int, int> pii;


int32_t main() {
    n = read(), m = read(), p = read();
    vector<int> a(n + 1);
    vector<vector<pii>> e(n + 1), g(n + 1);
    for (int u, v, c, d; m; m--) {
        u = read(), v = read(), c = read(), d = read();
        e[u].emplace_back(v, c);
        g[v].emplace_back(u, d);
    }

    vector<int> d1(n + 1, INF), d2(n + 1, LLONG_MAX);

    d1[1] = 0;
    priority_queue<pii, vector<pii>, greater<pii> > q;
    q.emplace(0, 1);
    vector<bool> vis(n + 1, false);
    while (!q.empty()) {
        auto [d, u] = q.top();
        q.pop();
        if (vis[u]) continue;
        vis[u] = true;
        for (auto [v, w]: e[u]) {
            if (vis[v] || d1[v] <= d + w) continue;
            d1[v] = d + w, q.emplace(d1[v], v);
        }
    }

    d2[n] = 0;
    q.emplace(0, n);
    vis = vector<bool>(n + 1, false);
    while (!q.empty()) {
        auto [d, u] = q.top();
        q.pop();
        if (vis[u]) continue;
        vis[u] = true;
        for (auto [v, w]: g[u]) {
            if (vis[v] || d2[v] <= d + w) continue;
            d2[v] = d + w, q.emplace(d2[v], v);
        }
    }

    for (int i = 1; i <= n; i++) a[i] = read();

    vector<int> b(n + 1, INF);
    multiset<int> ans;
    for (int i = 1; i <= n; i++) {
        if (d1[i] != LLONG_MAX && d2[i] != LLONG_MAX)
            b[i] = d1[i] + (d2[i] + a[i] - 1ll) / a[i];
        ans.insert(b[i]);
    }
    for (int x, y; p; p--) {
        x = read(), y = read();
        if (d1[x] != LLONG_MAX && d2[x] != LLONG_MAX) {
            ans.erase(ans.lower_bound(b[x]));
            a[x] = y, b[x] = d1[x] + (d2[x] + y - 1ll) / y;
            ans.insert(b[x]);
        }
        printf("%lld\n", *ans.begin());
    }
    return 0;
}

L3-2 还原文件

其实就是写一个暴搜,每次暴力匹配出可以放进去的碎片即可。

#include <bits/stdc++.h>
using namespace std;

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

int n , m;
vector<int> h;
vector<vector<int>> g;
vector<bool> vis;
vector<int> ans;

void dfs( int pos ){
	if( pos == n-1 ){
		for( auto i : ans )
			cout << i << " \n"[i==ans.back()];
		exit(0);
	}
	for( int i = 0 ; i < m ; i ++ ){
		if( vis[i] ) continue;
		bool flag = true;
		for( int j = 0 , k = pos ; flag && j < g[i].size() ; j ++ , k ++ )
			if( h[k] != g[i][j] ) flag = false;
		if( flag == false ) continue;
		vis[i] = true , ans.push_back(i+1);
		dfs( pos + g[i].size() - 1 );
		vis[i] = false , ans.pop_back();
	}
}

int main(){
	n = read();
	h = vector<int>(n);
	for( auto & i : h ) i = read();
	m = read();
	g = vector<vector<int>>(m);
	vis = vector<bool>(m , false);
	for( int i = 0 , x ; i < m ; i ++ ){
		x = read() , g[i] = vector<int>(x);
		for( int j = 0 ; j < x ; j ++ ) g[i][j] = read();
	}
	dfs( 0 );
	return 0;
}