天梯赛随笔

鱼和熊掌
思路:暴力判断一个物品被哪些人拥有,最后直接遍历查询交集即可

//鱼和熊掌
#include<bits/stdc++.h>
using namespace std;

constexpr int N = 1E5+10;
vector<int> v[N];
int flag[N];
int n, m;

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        int t; cin >> t;
        for (int j = 0; j < t; j ++) {
            int kd; cin >> kd;
            v[kd].push_back(i);
        }
    }
    int t; cin >> t;
    for (int i = 1; i <= t; i ++) {
        int a, b; cin >> a >> b;
        for (int x : v[a]) {
            flag[x] = i;
        }
        int ans = 0;
        for (int x : v[b]) {
            if (flag[x] == i) ans ++ ;
        }
        cout << ans << endl;
    }
}

懂蛇语

思路:字符串处理,用map映射对应的缩写,使用vector存储,可以在处理缩写时在开头加一个' '再进行判断。

//懂蛇语
#include<bits/stdc++.h>
#define siz(v) ((int)v.size())
using namespace std;

constexpr int N = 1E5;
int n, m;
map<string, vector<string>> mp;

string work(string s) {
    string res = "";
    s = " " + s;
    for (int i = 1; i < siz(s); i ++) {
        if (s[i-1] == ' ' && isalpha(s[i])) res += s[i];
    }
    return res;
}

int main() {
    cin >> n; getchar();
    for (int i = 1; i <= n; i ++) {
        string s; getline(cin, s);
        string sx = work(s);
        if (mp.count(sx) == 0) {
            vector<string> temp; temp.push_back(s);
            mp[sx] = temp;
        }
        else {
            auto &v = mp[sx]; v.push_back(s);
            mp[sx] = v;
        }
    }
    for (auto &[k, v] : mp) sort(v.begin(), v.end());
    cin >> m; getchar();
    for (int i = 1; i <= m; i ++) {
        string s; getline(cin, s);
        string sx = work(s);
        if (mp.count(sx) == 0) {
            cout << s << endl;
        } else {
            auto v = mp[sx];
            for (int i = 0; i < v.size(); i ++) {
                if (i) cout << '|';
                cout << v[i];
            }
            cout << endl;
        }
    }
}

满树的遍历
思路:vector数组存树边,存图过程中处理度数,后续检查+dfs即可

//满树的遍历
#include<bits/stdc++.h>
using namespace std;

constexpr int N = 1E5+10;
int deg[N], n, rt, ans;
vector<int> v[N];

void dfs(int fa) {
    if (fa != rt) cout << ' ';
    cout << fa;
    for (int x : v[fa]) {
        dfs(x);
    }
}

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

    cin >> n;
    for (int i = 1, t; i <= n; i ++) {
        cin >> t;
        if (t) {
            deg[t] ++; v[t].push_back(i);
            ans = max(ans, deg[t]);
        }
        else rt = i;
    }
    int ok = 1;
    for (int i = 1; i <= n; i ++) {
        sort(v[i].begin(), v[i].end());
        if (deg[i] != 0 && deg[i] != ans) {
            ok = 0;
        }
    }
    cout << ans << ' ';
    if (ok) cout << "yes" << endl;
    else cout << "no" << endl;

    dfs(rt);
}

吉祥矩阵

思路:爆搜+剪枝,每一行、每一列搜索至末尾时直接判断该填的数字,可行则继续搜索。对于其他位置只搜索范围内的数字

//吉祥矩阵
#include<bits/stdc++.h>
using namespace std;

int n, m, ans;
int row[5], col[5];
int a[5][5];

bool check() {
    for (int i = 0; i < n; i ++) {
        if (row[i] != m || col[i] != m) return false;
    }
    return true;
}

void dfs(int idx) {
    if (idx == n*n) {
        if (check()) ans ++;
        return;
    }
    int r = idx / n, c = idx % n;
    if (c == n-1) {
        int temp = m - row[r];
        if (m - col[c] >= temp) {
            a[r][c] = temp;
            col[c] += temp; row[r] += temp;
            dfs(idx+1);
            col[c] -= temp; row[r] -= temp;
        }
    }
    else if (r == n-1) {
        int temp = m - col[c];
        if (m - row[r] >= temp) {
            a[r][c] = temp;
            col[c] += temp; row[r] += temp;
            dfs(idx+1);
            col[c] -= temp; row[r] -= temp;
        }
    }
    else {
        for (int i = 0; i <= min(m-row[r], m-col[c]); i ++) {
            a[r][c] = i;
            row[r] += i; col[c] += i;
            dfs(idx+1);
            row[r] -= i; col[c] -= i;
        }
    }
}

int main() {
    cin >> m >> n;
    dfs(0);
    cout << ans << endl;
}
posted @ 2024-10-09 22:08  potatoJun  阅读(21)  评论(0)    收藏  举报