牛客小白月赛56

A 阿宁的柠檬

签到

#include<bits/stdc++.h>
#define int long long
using namespace std;


int32_t main() {
    int a , b , n;
    cin >> a >> b >> n;
    cout << n << " " << ( a + b ) * n << "\n";
    return 0;
}

B 阿宁与猫咪

最优的分发肯定是分成m个 1 ,这道题总感觉题面不是很通顺

#include<bits/stdc++.h>
#define int long long
using namespace std;

int32_t main() {
    int a;
    cin >> a;
    cout << a << "\n";
    for( int i = 1 ; i <= a ; i ++ )
        cout << "1 ";
    return 0;
}

C 阿宁吃粽子

首先容易知道的是,大的乘大的结果更优。

然后我们把整个队列分层若干组,第一组有 9 个,中间组有 10 个,最后一组有n%10

然后把所有人拍个序,依次分散到每个组里就好了。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5+5;
int n , a[N] , m , k, c[N];
vector<int> res[N];

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() {
    n = read() , m = n / 10 + 1 , k = n % 10 ;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    sort( a + 1 , a + 1 + n );
    if( n < 10 ){
        for( int i = 1 ; i <= n ; i ++ )
            cout << a[i] << " ";
        exit(0);
    }
    int id = 1;
    for( int i = 1 ; id <= n ; i = ( i + 1 ) % m ){
        if( i == m-1 && res[i].size() == k+1 ) continue;
        res[i].push_back( a[id++] );
    }
    for( int i = 0 ; i < m ; i ++ )
        for( auto it : res[i] )
            cout << it << " ";
}

D 阿宁的质数

把前n+1个质数全部找出来,然后放到一个 set 里面,对于序列 a,把前 i 位里的质数从 set 中删掉,然后输出最小的就是答案。可以自己枚举所有可能的情况然后静态回答就好了。

然后就是估计质数的个数用\(\frac{x}{\ln(x)}\)就好

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5+5;
int n , a[N] , m , k, c[N];
vector<int> res[N];

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() {
    n = read() , m = n / 10 + 1 , k = n % 10 ;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    sort( a + 1 , a + 1 + n );
    if( n < 10 ){
        for( int i = 1 ; i <= n ; i ++ )
            cout << a[i] << " ";
        exit(0);
    }
    int id = 1;
    for( int i = 1 ; id <= n ; i = ( i + 1 ) % m ){
        if( i == m-1 && res[i].size() == k+1 ) continue;
        res[i].push_back( a[id++] );
    }
    for( int i = 0 ; i < m ; i ++ )
        for( auto it : res[i] )
            cout << it << " ";
    return 0;
}

E 阿宁睡大觉

相邻的两个Z贡献是 4。先扫一遍字符串,统计所有的相邻的Z,同时统计不相邻的Z的间距,然后从小到大的删除

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5+5;
int n , m , res;
vector<int> v , q ;

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() {
    n = read() , m = read();
    string s;
    cin >> s;
    for( int i = 0 ; i < n ; i ++ )
        if( s[i] == 'Z' ) v.push_back(i);
    for( int i = 1 ; i < v.size() ; i ++ )
        if( v[i] - v[i-1] == 1 ) res += 4;
        else q.push_back( v[i] - v[i-1] - 1 );
    sort( q.begin() , q.end() );
    for( auto it : q ){
        if( it > m ) break;
        m -= it , res += 4;
    }
    cout << res << "\n";
}

F 阿宁去游玩

把其他所有的点异或1,等价于把当前点异或。考虑用 dij 求最短路,因为 dikstraj 不会走回头路,所以异或当前点产生的影响只会影响与当前点所连的边,这样的话如果两点相同边权就是min( x , y + z ),两点不同就是min(y , x + z )建好图跑一遍 dijkstra

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5+5;
int n , m , dis[N] , valX , valY , valZ;
vector<pair<int,int>> e[N];
bitset<N> state , vis;

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 D( int x , int y ){
    if( state[x] == state[y] ) return valX;
    return valY;
}

void dij(){
    fill( dis , dis + N , LLONG_MAX );
    dis[1] = 0;
    priority_queue< pair< int , int > , vector<pair< int , int >> , greater<pair< int , int >> > q;
    q.push( { 0 , 1 } );
    while( !q.empty() ){
        int u = q.top().second ; q.pop();
        if( vis[u] ) continue;
        vis[u] = 1;
        for( auto [ v , w ] : e[u] ){
            if( vis[v] || dis[v] <= dis[u]+w ) continue;
            dis[v] = dis[u] + w;
            q.push( { dis[v] , v } );
        }
    }
}

int32_t main() {
    n = read() , m = read();
    valX = read() , valY = read() , valZ = read();
    valX = min( valX , valY+valZ ) , valY = min( valY , valX + valZ );
    for( int i = 1 , x ; i <= n ; i ++ )
        state[i] = read();
    for( int u , v ; m ; m -- ){
        u = read() , v = read();
        e[u].push_back( { v , D(u,v) } ) , e[v].push_back( { u , D(u,v) } );
    }
    dij();

    cout << dis[n] << "\n";
}
posted @ 2022-09-08 19:23  PHarr  阅读(25)  评论(0编辑  收藏  举报