河南萌新聯賽2024第(二)場:南陽理工學院

PHarr發表於2024-07-25

A - 國際旅行Ⅰ

因為保證聯通,所以直接排序就好了

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;

i32 main() {
	int n, m, q;
	cin >> n >> m >> q;

	vi a(n);
	for(int &i : a) cin >> i;

	sort(a.begin(), a.end());

	for(int x, y; m; m --)
		cin >> x >> y;
	
	for(int x; q; q--){
		cin >> x, x--;
		cout << a[x] << "\n";
	}
	return 0;
}

D - A*BBBB

直接用高精度是不可以的,但是我們可以用先成一個\(b\)然後再乘法\(11111\)就可以,這樣的話就可以使用字首和模擬高精度就好了。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;

void solve() {
    string a, b;
    cin >> a >> b;
    reverse(a.begin(), a.end());
    int n = a.size(), m = b.size(), t = b[0] - '0';
    a = " " + a;
    vector<int> ans;
    int sum = 0, now = 0, carry = 0;
    for (int i = 1; i < n + m; i++) {
        if (i <= n) sum += a[i] - '0';
        if (i > m) sum -= a[i - m] - '0';
        now = (sum * t + carry) % 10;
        carry = (sum * t + carry) / 10;
        ans.push_back(now);
    }
    if (carry > 0) cout << carry;
    else {
        while (ans.size() > 1 and ans.back() == 0)
            ans.pop_back();
    }
    ranges::reverse(ans);
    for (auto i: ans) cout << i;
    cout << "\n";
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

E - “好”字元

\(b\)串存兩邊,題目就變成在\(b\)串查詢\(a\)串出現的次數。但是這裡要剔除其他字母的影響,所以可以用*表示一個萬用字元就好了。剩下用kmp就好了。

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;

vi prefix_function(const string &s){
	int n = s.size();
	vi pi(n);
	for(int i = 1, j; i < n; i ++) {
		j = pi[i - 1];
		while(j > 0 and s[i] != s[j]) j = pi[j - 1];
		if(s[i] == s[j]) j ++;
		pi[i] = j;
	}
	return pi;
}


bool kmp(const string &text, const string &pattern) {
	string cur = pattern + "#" + text;
	int n = text.size(), m = pattern.size();
	vi lps = prefix_function(cur);
	for(int i = m + 1; i <= n + m; i ++) {
		if(lps[i] == m) return true;
	}
	return false;
}

i32 main() {
	int n;
	cin >> n;
	string s, t;
	cin >> s >> t, t = t + t;
	vector<i.nt> cntS('z' + 1), cntT('z' + 1);
	for(auto i : s)
		cntS[i] = 1;
	for(auto i : t)
		cntT[i] = 1;

	int res = 0;
	for(char c = 'a'; c <= 'z'; c ++) {
		if( cntS[c] == 0 or cntT[c] == 0) continue;
		string ss = s, tt = t;
		for(auto &i : ss)
			if(i != c) i = '*';
		for(auto &i : tt)
			if(i != c) i = '*';
		if(kmp(tt, ss)) res ++;
	}
	cout << res;
	return 0;
}

F - 水靈靈的小學弟

兩個人都是DHY

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;

i32 main() {
	int n;
	cin >> n;
	while(n --) cout << "DHY\n";
	return 0;
}

G - 小w和大W的決鬥。

在二維網格中如果要想將軍隊合併,就需要知道每個軍隊之間的距離,我們可以跑bfs來實現,當知道每個點之 間的距離之後我們跑一下最小生成樹就可以知道最少多少天可以將軍隊合併了,如果軍隊與軍隊之間被阻擋無法到 達,則輸出No。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int, int>;

const int inf = INT_MAX / 2;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

class dsu {
private:
    vector<int> fa;
public:
    dsu(int n = 1) {
        fa = vector<int>(n + 1, -1), fa[0] = 0;
    }

    int getfa(int x) {
        if (fa[x] < 0) return x;
        return fa[x] = getfa(fa[x]);
    }

    void merge(int x, int y) {
        x = getfa(x), y = getfa(y);
        if (x == y) return;
        if (fa[x] > fa[y]) swap(x, y);
        fa[x] += fa[y], fa[y] = x;
    }

    bool same(int x, int y) {
        x = getfa(x), y = getfa(y);
        return (x == y);
    }
};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<pii> pos;

    vector<string> g(n);
    for (auto &gi: g) cin >> gi;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (g[i][j] == '*')
                pos.emplace_back(i, j), cerr << i << " , " << j << "\n";

    auto bfs = [=](int sx, int sy) {
        vector dis(n, vi(m, inf));
        queue<pii> q;
        q.emplace(sx, sy);
        dis[sx][sy] = 0;
        while (not q.empty()) {
            auto [x, y] = q.front();
            q.pop();
            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 (g[fx][fy] == '#') continue;
                if (dis[fx][fy] <= dis[x][y] + 1) continue;
                dis[fx][fy] = dis[x][y] + 1;
                q.emplace(fx, fy);
            }
        }
        return dis;
    };

    vector<array<int, 3>> edge;
    for (int i = 0; i < pos.size(); i++) {
        auto [xi, yi] = pos[i];
        auto dis = bfs(xi, yi);
        for (int j = 0; j < i; j++) {
            auto [xj, yj] = pos[j];
            if (dis[xj][yj] == inf) {
                cout << "No\n";
                return 0;
            }
            edge.push_back({dis[xj][yj], i + 1, j + 1});
        }
    }

    sort(edge.begin(), edge.end());
    int res = 0;
    int t = pos.size();
    dsu d(t);
    for (auto &[w, x, y]: edge) {
        if (d.same(x, y)) continue;
        res += w, d.merge(x, y);
    }
    cout << res;
    return 0;
}

H - 狼狼的備忘錄

小模擬,善用 STL 就好

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;


i32 main() {
	map<string, vector<string>> info;
	int T;
	for(cin >> T; T; T--) {
		string name;
		cin >> name;
		int k;
		for(cin >> k; k; k --){
			string s;
			cin >> s;
			info[name].push_back(s);
		}
	}
	for(auto &[name, it] : info){
		sort(it.begin(), it.end());
		it.resize(unique(it.begin(), it.end()) - it.begin());

		for(auto &s : it)
			reverse(s.begin(), s.end());

		vector<string> newIt;

		for(const auto &s: it){
			bool flag = false;
			for(const auto &t : it){
				if(t.size() < s.size() or s == t) continue;
				if(t.substr(0, s.size()) != s) continue;
				flag = true;
				break;
			}
			if(flag) continue;
			newIt.push_back(s);
		}
		for(auto &s: newIt)
			reverse(s.begin(), s.end());
		sort(newIt.begin(), newIt.end());
		it = move(newIt);
	}
	cout << info.size() << "\n";
	for(auto &[name, it]: info){
		cout << name << " " << it.size();
		for(auto s : it) cout << " " << s;
		cout << "\n";
	}
	return 0;
}

I - 重生之zbk要拿回屬於他的一切

暴力匹配

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;

i32 main() {
	int n;
	cin >> n;
	string s;
	cin >> s;

	int cnt = 0;
	for(int i = 0; i + 4 < n; i ++)
		cnt += s.substr(i, 5) == "chuan";
	cout << cnt;
	return 0;
}

J - 這是簽到

拉普拉斯展開

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;

int calc(vector<vector<int>> a){
	int n = a.size(), sum = 0;
	if(n == 1) return a[0][0];


	for(int i = 0; i < n; i ++){
		vector<vi> b;
		for(int j = 1; j < n; j ++ ){
			b.push_back(vi());
			for(int k = 0; k < n; k ++) {
				if(k == i) continue;
				b.back().push_back(a[j][k]);
			}
		}

		sum += a[0][i] * pow(-1, i) * calc(b);
	}
	return sum;
}

i32 main() {
	int n, m, N;
	cin >> n >> m, N = max(n, m);

	vector<vi> a(N, vi(N));
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < m; j ++)
			cin >> a[i][j];
	
	int res = INT_MAX;
	while(not a.empty()){
		res = min(res, calc(a));
		a.pop_back();
		for(auto &ai : a)
			ai.pop_back();
	}
	cout << res;
	return 0;
}

相關文章