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

A 中奖

结构体排序就好了,我是用 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;
}

E 排列计数

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

因为$\left \lceil n^2+\frac{n}{2} \right \rceil $,就是序列中的顺序对数量大于逆序对。

如果有一个序列的顺序对数量大于逆序对,那么这个序列的倒序就一定是顺序对少于逆序对。所以满足条件和不满足条件是序列应该是一样多的,都是\(\frac{A_{2n}^{2n}}{2} = \Pi_{i=3}^{2n} i\)

#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;
}

G 登山小分队

先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;
}

H 拼接的字符串

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

#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";
}

I 没有字母的数

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

#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;
}
posted @ 2022-07-05 19:10  PHarr  阅读(50)  评论(0编辑  收藏  举报