牛客小白月赛64

A.小杜要迟到了!

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


int32_t main(){
    int n , k , a , b , r1 , r2;
    cin >> n >> k >> a >> b;
    n -- , k --;
    r1 = ( n + k ) * b;
    r2 = n * a;
    if( r1 < r2 ) cout << 1;
    else if( r1 > r2 ) cout << 2;
    else cout << 0;

    return 0;
}

B.小杜捕鱼

离一个点曼哈顿距离最远的点一定在四个角上,因此算出四个角需要的距离,在取最小值即可。

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

int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n , m , res = 0;
    cin >> n >> m;
    vector<pair<int,int>> v;
    for( int i = 1 ; i <= n ; i ++ ){
        string s;
        cin >> s;
        for( int j = 1 ; j <= m ; j ++ )
            if( s[j-1] == '#' ) v.push_back(make_pair(i,j));
    }
    vector<pair<int,int>> a;
    a.push_back(make_pair(1,1));
    a.push_back(make_pair(1,m));
    a.push_back(make_pair(n,1));
    a.push_back(make_pair(n,m));

    auto dis = []( pair<int,int> a , pair<int,int> b ){
        return abs( a.first - b.first ) + abs( a.second - b.second );
    };

    for( auto i : a ){
        int ans = 0;
        for( auto j : v )
            ans = max( ans , dis(i,j) );
        res = max( res , ans );
    }
    cout << res << "\n";
    return 0;
}

C.Karashi的生日蛋糕

首先把每一圈的水果先给每个人分\(\frac i k\),这样还剩下\(i%k\)个,记录下来。之后对\(k\)个人按照已经有的水果总数排序,优先给水果少的,并且保证每次加一

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


int32_t main(){
    ios::sync_with_stdio(false) , cin.tie(nullptr);
    int n , k ;
    cin >> n >> k;
    vector<vector<int>> res( k , vector<int>( n+1 , 0 ) );

    for( int t , i = 1 ; i <= n ; i ++ ){
        t = i / k;
        for( int j = 0 ; j < k ; j ++ ) res[j][i] = t , res[j][0] += t;
    }

    for( int i = 1 ; i <= n ; i ++ ){
        if( i % k == 0) continue;
        sort( res.begin() , res.end() , []( const vector<int> & a , const vector<int> & b ){
            return a[0] < b[0];
        });
        for( int j = 0 ; j < i % k ; j ++ )
            res[j][i] ++ , res[j][0] ++;
    }

    for( int i = 0 ; i < k ; i ++ )
        for( int j = 1 ; j <= n ; j ++ )
            cout << res[i][j] << " \n"[j==n];
    return 0;
}

D.Karashi的树 I

其实任意一个点都可以换到任意位置上去,所以我们把点权排序,再把点按照子树大小排序,然后一一对应就是最优解。

#include<bits/stdc++.h>
#define int long long
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 n , res;
vector<int> a , val, si;
vector<pair<int,int>> cur;
vector<vector<int>> e;

void dfs( int x  ){
    si[x] = 1;
    for( auto v : e[x] ){
        dfs( v ) , si[x] += si[v];
    }
    cur.push_back(make_pair( si[x] , x ) );
    return;
}

void dfs( int x , int sum ){
    sum += val[x] , res += sum;
    for( auto v : e[x] ){
        dfs( v , sum );
    }
    return;
}

int32_t main(){
    n = read();
    val = si = a = vector<int>(n);
    e = vector<vector<int>>( n , vector<int>() );

    for( auto & i : a ) i = read();
    for( int fa , i = 1 ; i < n ; i ++ )
        fa = read() - 1 , e[fa].push_back(i);
    dfs( 0  );
    sort( cur.begin() , cur.end() );
    sort( a.begin() , a.end() );
    for( int i = 0 ; i < n ; i ++ )
        val[ cur[i].second ] = a[i];
    dfs( 0 , 0 );
    cout << res << "\n";
    return 0;
}

E.Karashi的数组 I

\(A=a[k] , B=\sum_{k+1}^{k+len} a[k] , C = a[k+len+1]\),则题目所给条件为\((A+B)\times(B+C)=(A+B+C)\times B\)

化简可得\(AC=0\)所以题目求的是\(k\in[1,n-len-1]\)中满足\(a[k]\times a[k+len+1]=0\)的个数

其实我们修改一点只会至多影响两个k是否成立,所以这道题\(O(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;
}

int m , n , len , cnt = 0;
vector<int> a;
void update( int p , int v ){
    if( p-len-1 >= 0 && a[p]*a[p-len-1] == 0 ) cnt--;
    if( p+len+1 < n && a[p]*a[p+len+1] == 0 ) cnt --;
    a[p] = v;
    if( p-len-1 >= 0 && a[p]*a[p-len-1] == 0 ) cnt++;
    if( p+len+1 < n && a[p]*a[p+len+1] == 0 ) cnt ++;
}

int32_t main(){
    n = read() , m = read() , len = read() , a.resize(n);

    for( auto & i : a ) i = read();
    for( int i = 0 ; i < n - len - 1 ; i ++ )
        if( a[i] * a[i+len+1] == 0 ) cnt ++;
    for( int p , v ; m ; m -- ){
        p = read() - 1 , v = read();
        update( p , v );
        cout << cnt << "\n";
    }
    return 0;
} 	
posted @ 2023-01-08 15:09  PHarr  阅读(37)  评论(0编辑  收藏  举报