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

1|0L1-1 今天我要赢


#include <bits/stdc++.h> using namespace std; int main() { cout << "I'm gonna win! Today!\n"; cout << "2022-04-23\n"; return 0; }

2|0L1-2 种钻石


#include <bits/stdc++.h> using namespace std; int main() { int a , b; cin >> a >> b; cout << a / b; return 0; }

3|0L1-3 谁能进图书馆


注意要做到不重不漏

#include <bits/stdc++.h> using namespace std; int main() { int a , b , c , d; cin >> a >> b >> c >> d; if( c < a && d < a ){ cout << c<<"-N " << d<<"-N\n"; cout << "zhang da zai lai ba\n"; }else if( c >= a && d >= a ){ cout << c<<"-Y " << d << "-Y\n"; cout << "huan ying ru guan\n"; }else if( min(c,d) < a && max(c,d) >= b ){ cout << c<<"-Y " << d << "-Y\n"; if( c > d ) cout << "qing 1 zhao gu hao 2\n"; else cout << "qing 2 zhao gu hao 1\n"; }else{ if( c > a ) cout << c << "-Y " << d << "-N\n" << "1: huan ying ru guan\n"; else cout << c << "-N " << d << "-Y\n"<< "2: huan ying ru guan\n"; } }

4|0L1-4 拯救外星人


#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { ll a , b , c = 1; cin >> a >> b; for( int i = 2 ; i <= a+b ; i ++ ) c *= i; cout << c; }

5|0L1-5 试试手气


#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { vector<set<int>> st(6); for( int i = 0 ; i < 6 ; i ++ ) for( int j = 1 ; j <= 6 ; j ++ ) st[i].insert(j); for( int i = 0 , x ; i < 6 ; i ++ ){ cin >> x; st[i].erase(x); } int n; cin >> n; for( n-= 1 ; n ; n -- ){ for( int i = 0 ; i < 6 ; i ++ ) st[i].erase( *st[i].rbegin() ); } for( int i = 0 ; i < 6 ; i ++ ) cout << *st[i].rbegin() << " \n"[i==5]; }

6|0L1-6 斯德哥尔摩火车上的题


#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { string a , b , c = "" , d = ""; cin >> a >> b; for( int i = 1 ; i < a.size() ; i ++ ){ if( a[i] % 2 == a[i-1]%2 ) c += max( a[i] , a[i-1] ); } for( int i = 1 ; i < b.size() ; i ++ ){ if( b[i] % 2 == b[i-1] % 2 ) d += max( b[i] , b[i-1] ); } if( c == d ) cout << c << "\n"; else cout << c << "\n" << d <<"\n"; }

7|0L1-7 机工士姆斯塔迪奥


#include <bits/stdc++.h> using namespace std; #define int long long typedef long long ll; int32_t main() { set<int> r , c; int n , m , q; cin >> n >> m >> q; for( int x , y ; q ; q -- ){ cin >> x >> y; if( x == 1 ) r.insert(y); else c.insert(y); } int res = 0; for( int i = 1 ; i <= n ; i ++ ){ if( c.count(i) ) continue; for( int j = 1 ; j <= m ; j ++ ){ if( r.count(j) ) continue; res ++; } } cout << res; }

8|0L1-8 静静的推荐


#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; } int32_t main() { int n = read() , k = read() , s = read() , res = 0; vector<int> a(300); for( int x , y ; n ; n -- ){ x = read() , y = read(); if( x < 175 ) continue; if( y >= s ) res ++; else a[x] ++; } for( int i = 175 ; i <= 290 ; i ++ ) res += min( a[i] , k ); cout << res ; }

9|0L2-1 插松枝


其实就是模拟题,多多读读题就好

#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; } int32_t main() { int n = read(), m = read(), k = read(); vector<int> pusher(n), box; vector<vector<int>> ans; for (auto &i: pusher) i = read(); reverse(pusher.begin(), pusher.end()); while (!pusher.empty() || !box.empty()) { vector<int> cur; if (!box.empty()) cur.push_back(box.back()), box.pop_back(); else cur.push_back(pusher.back()), pusher.pop_back(); while (cur.size() < k) { if (!box.empty() && box.back() <= cur.back()) cur.push_back(box.back()), box.pop_back(); else { while (!pusher.empty() && pusher.back() > cur.back() && box.size() < m) box.push_back(pusher.back()), pusher.pop_back(); if (!pusher.empty() && pusher.back() <= cur.back()) cur.push_back(pusher.back()), pusher.pop_back(); else break; } } ans.push_back(cur); } for (const auto &it: ans) { cout << it.front(); for (int i = 1; i < it.size(); i++) cout << " " << it[i]; cout << "\n"; } return 0; }

10|0L2-2 老板的作息表


把时间都转换成秒数,然后把区间都排个序,然后加上起止时间,逐个判断是否连贯即可

#include <bits/stdc++.h> using namespace std; int read() { int x = 0, ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); return x ; } int32_t main() { int n = read(); vector<pair<int, int>> a; a.emplace_back(0, 0), a.emplace_back(24 * 60 * 60 - 1, 24 * 60 * 60 - 1); for (int l, r, h, m, s; n; n--) { h = read(), m = read(), s = read(); l = (h * 60 + m) * 60 + s; h = read(), m = read(), s = read(); r = (h * 60 + m) * 60 + s; a.emplace_back(l, r); } sort( a.begin(), a.end()); for( int i = 1 , l , r , h , m , s; i < a.size() ; i ++ ){ if( a[i].first == a[i-1].second ) continue; l = a[i-1].second , r = a[i].first; s = l % 60 , l /= 60; m = l % 60 , l /= 60; h = l; printf("%02d:%02d:%02d - " , h , m , s ); s = r % 60 , r /= 60; m = r % 60 , r /= 60; h = r; printf("%02d:%02d:%02d\n" , h , m , s ); } return 0; }

11|0L2-3 龙龙送外卖


我们考虑如果需要访问的点的条件有两种,第一种是本身要访问这个点,第二种是这个点子树中有点需要被访问。

可以考虑用带权并查集去维护一下当前的需要访问的树的大小。如果要求回到起点的话,树上的每一条边访问两边。现在要求不回去,所以最后一个点走到最深的点,然后直接结束。答案就是2(n1)maxdepn是当前树的大小,maxdep是最大深度。

对于每一个新加入的点,递归的加到当前的树上即可,加的时候顺便维护一下最大深度就好。

#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; } vector<int> fa; vector<int> g, dep; int n, m, sta, maxDep; int getfa(int x) { if (fa[x] < 0) return x; return fa[x] = getfa(fa[x]); } void dfs(int x) { if (getfa(x) == sta) return; dfs(g[x]); dep[x] = dep[g[x]] + 1, maxDep = max(maxDep, dep[x]); fa[sta] += fa[x], fa[x] = sta; return; } int32_t main() { n = read(), m = read(), sta = -1; g = vector<int>(n + 1); dep = vector<int>(n + 1, 0); for (int i = 1; i <= n; i++) { g[i] = read(); if (g[i] == -1) sta = i; } fa = vector<int>(n + 1, -1); for (int u; m ; m--) { u = read(); if (getfa(u) != sta) dfs(u); cout << -2 * (fa[sta] + 1) - maxDep << "\n"; } return 0; }

12|0L2-4 大众情人


跑一个暴力的 Floyd,然后再暴力统计答案。

#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; } int32_t main() { int n = read(); vector<string> sex(n + 1); vector<int> F, M; vector<vector<int>> f(n + 1, vector<int>(n + 1, INT_MAX)); for (int i = 1, m; i <= n; i++) { cin >> sex[i], m = read(); for (int v, w; m; m--) v = read(), w = read(), f[i][v] = w; } for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) { if (i == k || f[i][k] == INT_MAX) continue; for (int j = 1; j <= n; j++) { if (i == j || k == j || f[k][j] == INT_MAX) continue; f[i][j] = min(f[i][j], f[i][k] + f[k][j]); } } for (int i = 1; i <= n; i++) { if (sex[i] == "F") F.push_back(i); else M.push_back(i); } vector<int> Fval, Mval; for (int i = 1, val; i <= n; i++) { val = -1; if (sex[i] == "F") { for (auto j: M) val = max(val, f[j][i]); if (Fval.empty()) Fval.resize(2), Fval[0] = val, Fval[1] = i; else if (Fval[0] == val) Fval.push_back(i); else if (Fval[0] > val) Fval.resize(2), Fval[0] = val, Fval[1] = i; } else { for (auto j: F) val = max(val, f[j][i]); if (Mval.empty()) Mval.resize(2), Mval[0] = val, Mval[1] = i; else if (Mval[0] == val) Mval.push_back(i); else if (Mval[0] > val) Mval.resize(2), Mval[0] = val, Mval[1] = i; } } for( int i = 1 ; i < Fval.size() ; i ++ ) printf("%d%c" , Fval[i] , " \n"[i==Fval.size()-1] ); for( int i = 1 ; i < Mval.size() ; i ++ ) printf("%d%c" , Mval[i] , " \n"[i==Mval.size()-1] ); return 0; }

13|0L3-1 千手观音


首先根据题目的条件把每一个单词当成一个点,根据题目的描述建有向图出来。然后跑拓扑序,注意这里的拓扑序使用优先队列来保证顺序无法确定时按照字典序排列。最后为了简化操作,我把单词全部哈希了一下。

#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; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int n; cin >> n; vector<vector<string>> g(n); unordered_map<string, unordered_set<string>> p; unordered_map<string, int> deg; for (auto &it: g) { string s, t; cin >> s, t = ""; for (const auto &i: s) { if (i == '.') it.push_back(t), deg[t], t = ""; else t += i; } it.push_back(t), deg[t]; } for (int i = 0, j; i < n; i++) { j = i + 1; if (g[i].size() != g[j].size()) continue; for (int k = 0; k < g[i].size(); k++) { if (g[i][k] == g[j][k]) continue; if (p[g[i][k]].insert(g[j][k]).second) deg[g[j][k]]++; break; } } vector<string> res; priority_queue<string, vector<string>, greater<string>> q; for (auto [k, v]: deg) if (v == 0) q.push(k); while (!q.empty()) { auto u = q.top(); q.pop(); res.push_back(u); for (auto v: p[u]) { deg[v]--; if (deg[v] == 0) q.push(v); } } for (int i = 0; i < res.size(); i++) cout << res[i] << ".\n"[i == res.size() - 1]; return 0; }

14|0L3-2 关于深度优先搜索和逆序对的题应该不会很难吧这件事


首先如果每个点有vi个子节点,这dfs序的总数为(vi!),记作cnt

如果a<b,并且ba的祖先节点,在所有的 dfs序中都会有这个逆序对,贡献是cnt,这里的统计可以用树状数组实现

如果a<b,并且ab没有祖先关系,根据 dfs序的性质,在cnt2个序中a,b会形成逆序对,贡献cnt2。我们其实没有必要统计对于当前的a有多少个b满足大与a,而是有多少个ba没有祖先关系,其实就是所有的点去掉a的祖先节点们再去掉a的子树中的节点,这个可以用dfs统计。但注意,这样会导致重复统计,在统计a的时候会计入b,在统计b的时候又会计入a,为此我们可以把贡献修改为cnt4即可

思路来源

#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 mod = 1e9 + 7; int n, sta, cnt = 1, s1, s2; vector<int> b, fact, sz; vector<vector<int>> e; int power(int x, int y) { int ans = 1; while (y) { if (y & 1) ans = ans * x % mod; y >>= 1, x = x * x % mod; } return ans; } int inv(int x) { return power(x, mod - 2); } #define lowbit(x) ( x & -x ) void add(int x, int y) { for (int i = x; i <= n; i += lowbit(i)) b[i] += y; return; } int get(int x) { int ans = 0; for (int i = x; i; i -= lowbit(i)) ans += b[i]; return ans; } void dfs(int u, int fa, int dep) { add(u, 1); if (fa == -1) cnt = cnt * fact[e[u].size()] % mod; else cnt = cnt * fact[e[u].size()-1] % mod; s1 = (s1 + get(n) - get(u)) % mod; for (auto v: e[u]) { if (v == fa) continue; dfs(v, u, dep + 1); sz[u] += sz[v]; } s2 = (s2 + n - dep - sz[u]) % mod; add(u, -1); return; } int32_t main() { n = read(), sta = read(); b = vector<int>(n + 1), fact = vector<int>(n + 1); sz = vector<int>(n + 1, 1), sz[0] = 0; fact[0] = 1; for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % mod; e = vector<vector<int>>(n + 1); for (int i = 1, u, v; i < n; i++) u = read(), v = read(), e[u].push_back(v), e[v].push_back(u); dfs(sta, -1, 0); cout << (s1 * cnt % mod + s2 * cnt % mod * inv(4) % mod) % mod; return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17311365.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示