2020 团体程序设计天梯赛 个人题解 + 反思

L2的口罩发放也印象十分深刻，细节很多的大模拟.

L1-066 猫是液体 (5 分)

$V = L · H · W$

L1-067 洛希极限 (10 分)

void solve() {
double b1, b2, s;
cin >> b1 >> s >> b2;
double ans = 0;
if (s == 1) ans = b1 * 1.26;
else
ans = b1 * 2.455;
cout << fixed << setprecision(2) << ans << " ";
cout << ((ans - b2) <= 1e-6 ? "^_^\n" : "T_T\n");
}


L1-068 调和平均 (10 point(s))

void solve() {
double ans = 0.0;
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
double x;
cin >> x, ans += 1.0 / x;
}
ans = n * 1.0 / ans;
cout << fixed << setprecision(2) << ans;
}


L1-069 胎压监测 (15 分)

void solve() {
int a[5] = {0}, Min, FZ, cnt = 0;
int Max = -1, idx;
for (int i = 1; i <= 4; ++i) {
cin >> a[i];
if (Max < a[i]) Max = a[i], idx = i;
}
cin >> Min >> FZ;
vector<int> Idx;
for (int i = 1; i <= 4; ++i)
if (abs(a[i] - Max) > FZ || a[i] < Min) cnt++, Idx.push_back(i);

if (cnt == 0) cout << "Normal";
else if (cnt == 1)
cout << "Warning: please check #" << Idx[0] << "!";
else
cout << "Warning: please check all the tires!";
}


L1-070 吃火锅 (15 分)

void solve() {
string s;
vector<int> Idx;
int cnt = 0;
while (getline(cin, s)) {
if (s == ".") break;
cnt++;
if (s.find("chi1 huo3 guo1") < s.size()) Idx.push_back(cnt);
}
cout << cnt << "\n";
if (Idx.size() == 0) cout << "-_-#";
else
cout << Idx[0] << " " << Idx.size();
}


L1-071 前世档案 (20 point(s))

void solve() {
int n, m;
cin >> n >> m;
int t = pow(2, n);
for (int i = 0; i < m; i++) {
string s;
cin >> s;
int root = 1;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'y') root = root * 2;
else
root = root * 2 + 1;
}
cout << root - t + 1 << '\n';
}
}


L1-072 刮刮彩票 (20 point(s))

L1里最麻烦的模拟题了，这里就没放代码了。

L2，L3级别的题这里只写个人需要记录的

L2-034 口罩发放 (25 point(s))

#include <bits/stdc++.h>
using namespace std;
const int N = 1100;
struct edge {

string name;
string id;
int heal;
int times;
int ci;
};
int D, P, S, T;
bool check(string id) {
if (id.size() != 18) {
return false;
}

for (int i = 0; i < 18; i++) {
if (id[i] < '0' || id[i] > '9') {
return false;
}
}
return true;
}

bool cmp(edge e1, edge e2) {
if (e1.times == e2.times) {
return e1.ci < e2.ci;
}
return e1.times < e2.times;
}
map<string, int> mp;
set<string> st;
vector<pair<string, string>> res;
int main() {
cin >> D >> P;

for (int i = 1; i <= D; i++) {
cin >> T >> S;
vector<edge> v;
for (int j = 0; j < T; j++) {
edge e;
int a, b;
cin >> e.name >> e.id >> e.heal;
scanf("%d:%d", &a, &b);
e.times = a * 60 + b;
e.ci    = j;
if (check(e.id)) {
if (e.heal == 1) {
if (!st.count(e.id)) {
st.insert(e.id);
res.push_back({e.name, e.id});
}
}
v.push_back(e);
}
}
sort(v.begin(), v.end(), cmp);

vector<pair<string, string>> ans;
for (auto &x : v) {
string id = x.id;
if (S == 0) break;
if (mp[id] <= i) {
mp[id] = i + P + 1;
ans.push_back({x.name, x.id});
S--;
}
}

for (auto &x : ans) {
cout << x.first << ' ' << x.second << endl;
}
}
for (auto &x : res) {
cout << x.first << ' ' << x.second << endl;
}
return 0;
}


L2-035 完全二叉树的层序遍历 (25 point(s))

      1
2    3
4  5  6  7
8


// Murabito-B 21/04/21
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Node {
int data;
int l, r;
} node[40];
void dfs(int d) { // 递归建树
if (node[d].l != 0) dfs(node[d].l);
if (node[d].r != 0) dfs(node[d].r);
cin >> node[d].data;
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
if (i * 2 <= n) node[i].l = i * 2;
if (i * 2 + 1 <= n) node[i].r = i * 2 + 1;
}
dfs(1);
cout << node[1].data;
for (int i = 2; i <= n; ++i) cout << " " << node[i].data;
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}


L2-036 网红点打卡攻略 (25 point(s))

• 给你一个路径，判断这条路径是否是一个NP完全问题的解，如果是找出路径最短的那个解，而且还得记录有多少个正确的解
• 这个题要判断给的点是否是n个不同的点就好了。1、p等于n。2、这p个点没有重复的点
#include <bits/stdc++.h>
using namespace std;
using ll    = long long;
const int N = 210;
int n, m;
int k, p;
int g[N][N];
ll id, ans = 1e9;
ll sum;
bool check() {
sum = 0, sum += g[0][road[1]];
for (int i = 1; i < p; ++i) {
sum += g[x][y];
}

if (sum >= 1e9) return false;
return true;
}
void solve() {
cin >> n >> m;
memset(g, 0x3f, sizeof(g));

for (int i = 0, a, b, c; i < m; ++i) {
cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b], c);
}

cin >> k;
int cnt = 0;
for (int i = 1; i <= k; ++i) {
cin >> p;
set<int> ss;
for (int j = 1; j <= p; ++j) {
}

if (p == n && ss.size() == n && check()) {
if (ans > sum) ans = sum, id = i;
cnt++;
}
}
cout << cnt << "\n"
<< id << " " << ans << '\n';
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}


L3-025 那就别担心了 (30 point(s))

骗分做法：

“逻辑自洽” 和 拓扑排序是一样的所以我们可以检查出度为 $0$ 的个数

// Murabito-B 21/04/21
#include <bits/stdc++.h>
using namespace std;
using ll       = long long;
const int MAXN = 550;
int N, M;
int e[MAXN][MAXN];
int A, B;
int cnt = 0;
struct node { // 检验入度和出度
int in, to;
} dist[MAXN];
bool vis[MAXN];
void dfs(int x) {
if (x == B) {
cnt++;
return;
}
for (int i = 1; i <= N; ++i) {
if (vis[i] == false && e[x][i]) {
vis[i] = true;
dfs(i);
vis[i] = false;
}
}
}
void solve() {
cin >> N >> M;
for (int i = 1, s1, s2; i <= M; ++i) {
cin >> s1 >> s2;
e[s1][s2] = 1;
dist[s2].in++;
dist[s1].to++;
}
cin >> A >> B;
vis[A] = true;
dfs(A);
cout << cnt << " ";
int ans = 0;
for (int i = 1; i <= N; ++i)
if (dist[i].to == 0) ans++;

cout << (ans == 1 ? "Yes\n" : "No\n");
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}


// Murabito-B 21/04/21
#include <bits/stdc++.h>
using namespace std;
using ll    = long long;
const int N = 1e6 + 10;
vector<int> e[N];
int n, m;
int S, E;
int cnt;
bool f = true;
void dfs(int u) {
if (u == E) {
cnt++;
return;
}
if (u != E)
if (e[u].size() == 0) f = false;

for (int i = 0; i < e[u].size(); ++i)
dfs(e[u][i]);
}
void solve() {
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
e[a].push_back(b);
}
cin >> S >> E;
dfs(S);
cout << cnt << " " << (f ? "Yes\n" : "No\n");
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}


AC解法

AC 代码：

// Murabito-B 21/04/21
#include <bits/stdc++.h>
using namespace std;
using ll    = long long;
const int N = 1e6 + 10;
vector<int> e[N];
int n, m;
int S, E;
int cnt[N];
bool vis[N];
bool f = true;
int dfs(int u) {
// 不是终点但也不难往下走了，即出度为0
if (u != E)
if (e[u].size() == 0) f = false;
vis[u] = true;
if (cnt[u]) return cnt[u];
for (int i = 0; i < e[u].size(); ++i)
cnt[u] += dfs(e[u][i]);
return cnt[u];
}
void solve() {
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
e[a].push_back(b);
}
cin >> S >> E;
cnt[E] = 1;
dfs(S);
cout << cnt[S] << " " << (f ? "Yes\n" : "No\n");
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}

posted @ 2021-04-19 21:17  RioTian  阅读(26)  评论(1编辑  收藏