西南民族大学2023天梯选拔赛

1|0L1-1 谢谢卡尔!


print("谢谢卡尔!\\(>_<)/")

2|0L1-2 现在是,幻想时间!


#include <bits/stdc++.h> using namespace std; int main(){ double a , b; cin >> a >> b; printf("%.3lf" , a / b ); }

3|0L1-3 你是来陪可莉炸鱼的吗?


#include <bits/stdc++.h> using namespace std; int main() { int n, res = 0; cin >> n; for (int x; n; n--) { cin >> x; if (x < 100) res += 1; else if (x < 200) res += 2; else if (x < 300) res += 5; else if (x < 400) res += 10; else res += 15; } cout << res; }

4|0L1-4 扫雷游戏


#include <bits/stdc++.h> using namespace std; int f[15][15], n, m; const int dx[] = {0, 0, 1, -1, 1, 1, -1, -1}; const int dy[] = {1, -1, 0, 0, 1, -1, 1, -1}; int main() { cin >> n >> m; string s; for (int i = 1; i <= n; i++) { cin >> s; for (int j = 1; j <= m; j++) { if (s[j - 1] == '.') continue; f[i][j] = INT_MIN; for (int k = 0; k < 8; k++) f[i + dx[k]][j + dy[k]]++; } } for( int i = 1 ; i <= n ; i ++ ){ for( int j = 1 ; j <= m ; j ++ ){ if( f[i][j] == 0 ) cout << "."; else if( f[i][j] < 0 ) cout << "*"; else cout << f[i][j]; } cout << "\n"; } }

5|0L1-5 史莱姆


#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; } int main() { int n = read(); vector<char> b; string s; cin >> s; for( auto i : s ){ if( b.empty() ) b.push_back(i); else if( i != b.back() ) b.push_back(i); } cout << b.size() << "\n"; for( auto i : b ) cout << i; }

6|0L1-6 加密通信


#include <bits/stdc++.h> using namespace std; int main() { int n, k; string s; cin >> n >> k >> s; vector<int> key(26); for (auto &i: key) cin >> i; k %= n , k = n - k; for (int i = k; i < n; i++) cout << key[s[i] - 'a']; for (int i = 0; i < k; i++) cout << key[s[i] - 'a']; }

7|0L1-7 字符操作


#include <bits/stdc++.h> using namespace std; int main() { int n; string s , v[2]; int a = 0 , b = 1; cin >> n >> s; v[0] = s.substr(0,n) , v[1] = s.substr(n,n); int m; cin >> m; for( int op , x , y , p , q ; m ; m -- ){ cin >> op >> x >> y; if( op == 2 ) swap( a , b ); else { x -= 1 , y -= 1; if( x < n ) p = a; else p = b , x -= n; if( y < n ) q = a; else q = b , y -= n; swap( v[p][x] , v[q][y] ); } } cout << v[a] << v[b]; }

8|0L1-8 vivo50!


#include <bits/stdc++.h> using namespace std; struct Stu{ string name; double gpa , all; int de , zhi; Stu( string name , int gpa , int de , int zhi ) :name(name) , gpa(gpa) , de(de) , zhi(zhi){ all = double( gpa + zhi ) * 0.7 + 0.3 * de; } bool operator < ( Stu b ){ if( all != b.all ) return all > b.all; return name < b.name; } }; int main() { int n , k; cin >> n >> k; vector<Stu> s; string name; double gpa; int de , zhi; for( int i = 1 , g ; i <= n ; i ++ ){ cin >> name >> gpa >> de >> zhi >> g; if( g == 0 ) continue; s.emplace_back( name , gpa * 10 + 50 , min( de + 70 , 100 ) , zhi ); } sort( s.begin(), s.end() ); for( int i = 0 , rk ; i < s.size() ; i ++ ){ if( i != 0 && s[i].all == s[i-1].all ) rk = rk; else rk = i + 1; if( rk > k ) break; cout << rk << " " << s[i].name; printf(" %.1lf\n" , s[i].all ); } }

9|0L2-1 游戏圈


就用并查集维护一下就好了

#include <bits/stdc++.h> using namespace std; 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 check( int x , int y ){ x = getfa(x) , y = getfa(y); return ( x == y ); } }; 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; } int main() { int n = read() , m = read() , q = read(); dsu t(n); for( int u , v ; m ; m -- ){ u = read() , v = read(); t.merge( u , v ); } for( int x , y ; q ; q -- ){ x = read() , y = read(); if( t.check(x,y) ) printf("yes\n"); else printf("no\n"); } int cnt = 0; for( int i = 1 ; i <= n ; i ++ ){ if( t.getfa(i) == i ) cnt ++; } cout << cnt << "\n"; }

如果不会并查集的话当然也可以用搜索搞一搞

#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() , q = read() , cnt = 0; vector<vector<int>> e(n+1); for( int a , b ; m ; m -- ) a = read() , b = read() , e[a].push_back(b) , e[b].push_back(a); vector<int> vis( n+1 ); for( int i = 1 ; i <= n ; i ++ ){ if( vis[i] ) continue; cnt ++; queue<int> q; q.push(i); while( !q.empty() ){ int u = q.front(); q.pop(); if( vis[u] ) continue; vis[u] = i; for( auto v : e[u] ){ if( vis[v] ) continue; q.push(v); } } } for( int a , b ; q ; q -- ){ a = read() , b = read(); if( vis[a] != vis[b] ) printf("no\n"); else printf("yes\n"); } printf("%d\n" , cnt ); return 0; }

10|0L2-2 组套题


模拟题,没什么算法,注意细节就好了。然后就是如何处理读入和输入可以采用格式化的形式,比较方便。

#include <bits/stdc++.h> using namespace std; int32_t main() { int n; scanf("%d" , &n ); vector<int> a(11); for (int i = 1; i <= 10; i++) scanf("%d" , &a[i] ); vector<tuple<int, int, int> > v; vector<queue<pair<int, int>>> q(11); for (int m, id = 1; id <= n; id++) { scanf("%d" , &m); for ( int x , y ; m; m--) { scanf(" T%d-%d" , &x ,&y ); if (a[x] > 0) a[x]--, v.emplace_back(x, id, y); else q[x].emplace(id, y); } getchar(); } for (int i = 1; i <= 10; i++) { if (a[i] == 0) continue; for (int j = i + 1; a[i] && j <= 10; j++) { while (!q[j].empty() && a[i]) a[i]--, v.emplace_back(j, q[j].front().first, q[j].front().second), q[j].pop(); } for (int j = i - 1; a[i] && j >= 1; j--) { while (!q[j].empty() && a[i]) a[i]--, v.emplace_back(j, q[j].front().first, q[j].front().second), q[j].pop(); } } sort(v.begin(), v.end()); for( auto it : v ) printf("%d-%d%c" , get<1>(it) , get<2>(it) , " \n"[it==v.back()]); return 0; }

11|0L2-3 简单的数数


比较典的 dp题,f[i][j]表示前i个数够成j的方案数

#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; } const int mod = 998244353; int main() { int n = read(); vector<array<int, 10> > f(n + 1);; for (int i = 1, x; i <= n; i++) { x = read(); if (i == 1) { f[i][x] = 1; continue; } for (int j = 0; j < 10; j++) { if (f[i - 1][j]) { f[i][(j + x) % 10] = (f[i][(j + x) % 10] + f[i - 1][j]) % mod; f[i][(j * x) % 10] = (f[i][(j * x) % 10] + f[i - 1][j]) % mod; } } } for (int i = 0; i <= 9; i++) cout << f[n][i] << "\n"; return 0; }

12|0L2-4 回家日


首先,是我赛时的做法,就是按照解封的顺序把点加入到图中,如果这个点通过一条边直接相连的点也已经解封就把边也加入进来,然后用并查集动态的维护联通性,每次更新完一个点就把逐个判断剩余的点中是否有和k联通的点

#include <bits/stdc++.h> using namespace std; 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 check(int x, int y) { x = getfa(x), y = getfa(y); return (x == y); } }; 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; } int main() { int n = read(), m = read(), k = read(); dsu d(n); vector<int> a(n + 1), p(n + 1, -1); for (int i = 1; i <= n; i++) a[i] = read(); vector<vector<int>> e(n + 1, vector<int>()); for (int u, v; m; m--) u = read(), v = read(), e[u].push_back(v), e[v].push_back(u); int t = 1; for (; t <= n; t++) { p[a[t]] = 0; for (auto v: e[a[t]]) { if (p[v] == 0) d.merge(v, a[t]); } if (a[t] == k) break; } unordered_set<int> st; for (int i = 1; i <= n; i++) { if (p[i] == 0 && d.check(i, k) == true) p[i] = t; else st.emplace(i); } t ++; for (; t <= n; t++){ p[ a[t] ] = 0; for (auto v: e[a[t]]) { if (p[v] >= 0) d.merge(v, a[t]); } vector<int> cur; for( auto j : st ) if( p[j] == 0 && d.check( j , k ) == true ) p[j] = t , cur.push_back(j); for( auto j : cur ) st.erase(j); } for( int i = 1 ; i <= n ; i ++ ) printf("%d%c" , p[i] , (" \n"[i==n])); return 0; }

然后正确实际上,我们可以用 bfs 的方式来维护这张图dis[i]表示ik路径上的最大值,从起点开始搜索就好了。

#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(), sta = read(); vector<int> a(n + 1); for (int i = 1 , x ; i <= n; i++) x = read() , a[x] = i ; vector<vector<int>> e(n + 1); for (int u, v; m; m--) u = read(), v = read(), e[u].push_back(v), e[v].push_back(u); vector<int>dis(n + 1, INT_MAX); dis[sta] = a[sta]; queue<int> q; q.emplace(sta); while (!q.empty()) { auto u = q.front(); q.pop(); for (auto v: e[u]) { if( dis[v] <= max( a[v] , dis[u] ) ) continue; dis[v] = max( a[v] , dis[u] ) , q.emplace( v ); } } for( int i = 1 ; i <= n ; i ++ ) printf("%d%c" , dis[i] , " \n"[i==n] ); return 0; }

然后可以优化这个搜索过程,通过优先队列优化搜索顺序,并且保证每个点只扩展一次。

#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(), sta = read(); vector<int> a(n + 1); for (int i = 1 , x ; i <= n; i++) x = read() , a[x] = i ; vector<vector<int>> e(n + 1); for (int u, v; m; m--) u = read(), v = read(), e[u].push_back(v), e[v].push_back(u); vector<int>dis(n + 1, INT_MAX); dis[sta] = a[sta]; queue<int> q; q.emplace(sta); while (!q.empty()) { auto u = q.front(); q.pop(); for (auto v: e[u]) { if( dis[v] <= max( a[v] , dis[u] ) ) continue; dis[v] = max( a[v] , dis[u] ) , q.emplace( v ); } } for( int i = 1 ; i <= n ; i ++ ) printf("%d%c" , dis[i] , " \n"[i==n] ); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17258657.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示