第20届上海大学程序设计联赛夏季赛

1|0A 中奖


结构体排序就好了,我是用 pair ,存相反数

#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 N = 2005; pair< int , pair<int,int> > a[N]; int n , m ; int32_t main() { cin >> n >> m; for( int i = 1 ; i <= n ; i ++ ) a[i].second.first = read() , a[i].second.second = read() , a[i].first = read() * -1; sort( a + 1 , a + 1 + n ); for( int i = 1 ; i <= m ; i ++ ) cout << a[i].second.first << " " << a[i].second.second << " " << a[i].first * -1 << endl; return 0; }

2|0E 排列计数


因为长度是2n,所以一共有2n2n对数,然后2n2n是奇数,并且一个对不是顺序对就是逆序对,所以顺序对和逆序对数量不可能相等。

因为n2+n2,就是序列中的顺序对数量大于逆序对。

如果有一个序列的顺序对数量大于逆序对,那么这个序列的倒序就一定是顺序对少于逆序对。所以满足条件和不满足条件是序列应该是一样多的,都是A2n2n2=Πi=32ni

#include<bits/stdc++.h> #define int long long using namespace std; const int mod = 1e9+7; int n , ans = 1; int32_t main() { cin >> n; n <<= 1; for( int i = 3 ; i <= n ; i ++ ) ans = ans * i % mod; cout << ans << endl; }

3|0G 登山小分队


先DFS一遍找到左右的叶子结点,并确定这里图中的父子关系。然后模拟这个登上的过程就好了,每次每个节点都只能向父节点移动一个人。

#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 N = 1005; int n , a[N] , fa[N] , cnt , res; vector<int> e[N] , del; bitset<N> vis; set< int > var;// 当前有人的节点 void dfs( int u ){ vis[u] = 1; bool f = 1; for( auto v : e[u] ){ if( vis[v] ) continue; fa[v] = u , f = 0; dfs( v ); } if( f ) a[u] = 1 , var.insert(u) , cnt ++; vis[u] = 0; } int32_t main() { n = read(); for( int i = 1 , u , v ; i < n ; i ++ ) u = read() , v = read() , e[u].push_back(v) , e[v].push_back(u); dfs( 1 ); while( a[1] != cnt ){ del.clear() , res ++; for( auto u : var ){ a[u] -- , a[ fa[u] ] ++; if( fa[u] != 1 && a[ fa[u] ] == 1 ) var.insert( fa[u] ); } for( auto u : var ) // 统计那些节点没人了 if( a[u] == 0 ) del.push_back(u); for( auto it : del ) // 删掉没人的节点 var.erase(it); } cout << res << endl; }

4|0H 拼接的字符串


枚举一下前缀的长度加几个判断就好

#include<bits/stdc++.h> using namespace std; string t , r; int n , m; int32_t main() { cin >> t >> r; n = t.size() , m = r.size(); if( n <= m ) { if( t == r.substr( 0 , n ) ) printf("YES\n") , exit(0); if( t == r.substr( m-n , n ) ) printf("YES\n") , exit(0); for( int i = 1 , j = n - 1 ; i < m && j > 0 ; i ++ , j -- ){ if( t == r.substr( 0 , i ) + r.substr( m-j , j ) ) printf("YES\n") , exit(0); } } else { if( t == r + r.substr( n-m , n-m ) ) printf("YES\n") , exit(0); } cout << "NO\n"; }

5|0I 没有字母的数


模拟一下进制转换的过程就好了

#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 N = 1e6+5; int s[N]; int32_t main() { for( int i = 1 , flag , x ; i <= 1e6 ; i ++ ){ flag = 1 , x = i; while( x && flag){ if( x % 16 > 9 ) flag = 0; else x /= 16; } s[i] = s[i-1] + flag; } int n , l , r ; for( n = read() ; n ; n -- ){ l = read() , r = read(); printf("%d\n" , s[r] - s[l-1] ); } return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/16448317.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示