天梯赛L2题解(049-052)
L2-049 鱼与熊掌
set搞一下就行了
#include <bits/stdc++.h>
using namespace std;
#define int long long
void ylh_() {
int n, m;
cin >> n >> m;
vector<set<int>> st(n + 1);
for (int i = 1; i <= n; ++i) {
int k;
cin >> k;
for (int j = 1; j <= k; ++j) {
int x;
cin >> x;
st[i].insert(x);
}
}
int q;
cin >> q;
while (q--) {
int x, y;
cin >> x >> y;
int ans = 0;
for (int i = 1; i <= n; ++i) {
if (st[i].count(x) && st[i].count(y)) {
++ans;
}
}
cout << ans << '\n';
}
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) {
ylh_();
}
}
L2-050 懂蛇语
注意空格分隔不止一个空格,所以要用getline读入
#include <bits/stdc++.h>
using namespace std;
#define int long long
void ylh_() {
int n;
cin >> n;
map<string, vector<string>> mp;
for (int i = 1; i <= n; ++i) {
string s = "", t = "";
if (i == 1) {
getline(cin, s);
}
getline(cin, s);
for (int i = 0; i < s.length(); ++i) {
if (s[i] >= 'a' && s[i] <= 'z' && (i == 0 || s[i - 1] == ' ')) {
t += s[i];
}
}
mp[t].push_back(s);
}
for (auto& [x, vec] : mp) {
sort(vec.begin(), vec.end());
}
int m;
cin >> m;
for (int i = 1; i <= m; ++i) {
string s = "", t = "";
if (i == 1) {
getline(cin, s);
}
getline(cin, s);
for (int i = 0; i < s.length(); ++i) {
if (s[i] >= 'a' && s[i] <= 'z' && (i == 0 || s[i - 1] == ' ')) {
t += s[i];
}
}
if (!mp[t].size()) {
cout << s << '\n';
}
for (int i = 0; i < mp[t].size(); ++i) {
cout << mp[t][i] << "|\n"[i == mp[t].size() - 1];
}
}
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) {
ylh_();
}
}
L2-051 满树的遍历
其实我不太懂这种非二叉树的前序遍历是个什么玩意,于是按顺序遍历试了一下发现过了
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MOD = 998244353;
using PII = pair<int, int>;
void ylh_() {
int n;
cin >> n;
vector<vector<int>> g(n + 1);
int rt = -1;
vector<int> degree(n + 1); // 度数的出现次数
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
if (x == 0)
rt = i;
else {
g[x].push_back(i);
}
}
vector<int> ans;
auto dfs = [&](auto&& dfs, int u) -> void {
int deg = 0;
ans.push_back(u);
for (auto v : g[u]) {
dfs(dfs, v);
++deg;
}
degree[deg]++;
};
dfs(dfs, rt);
int cnt = 0;
int Max = -1;
for (int i = 0; i <= n; ++i) {
if (degree[i] != 0) {
++cnt;
Max = i;
}
}
if (cnt >= 3) {
cout << Max << ' ' << "no" << '\n';
} else {
cout << Max << ' ' << "yes" << '\n';
}
for (int i = 0; i < n; ++i) {
cout << ans[i] << " \n"[i == n - 1];
}
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) {
ylh_();
}
}
L2-052 吉利矩阵
其实就是爆搜剪枝,我想了一下数据小就没仔细思考了,每次剪一点点剪了三次小点就过了
可以专门用数组记录行列和,然后超出就剪枝
实际上可以根据每行或者每列的前n -1个数确定最后一个数,可以缩小指数
甚至可以得出答案后打表也是可以的
#include <bits/stdc++.h>
using namespace std;
#define int long long
using PII = pair<int, int>;
void ylh_() {
int l, n;
cin >> l >> n;
vector<vector<int>> a(n + 1, vector<int>(n + 1));
int ans = 0;
auto dfs = [&](auto&& dfs, int x, int y) -> void {
if (x == n + 1) {
for (int j = 1; j <= n; j++) {
int s = 0;
for (int i = 1; i <= n; i++)
s += a[i][j];
if (s != l)
return;
}
ans++;
return;
}
if (y == n + 1) {
int s = 0;
for (int i = 1; i <= n; i++)
s += a[x][i];
if (s != l)
return;
dfs(dfs, x + 1, 1);
return;
}
int s = 0;
for (int i = 1; i < y; i++)
s += a[x][i];
if (s > l)
return;
s = 0;
for (int i = 1; i < x; ++i) {
s += a[i][y];
}
if (s > l)
return;
for (int v = 0; v <= l; v++) {
if (s + v > l)
continue;
a[x][y] = v;
if (x == n) {
int t = 0;
for (int i = 1; i <= n; i++)
t += a[i][y];
if (t != l)
continue;
}
dfs(dfs, x, y + 1);
}
};
dfs(dfs, 1, 1);
cout << ans << '\n';
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) {
ylh_();
}
}

浙公网安备 33010602011771号