AtCoder Beginner Contest 267

A - Saturday

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

int32_t main() {
    string s;
    cin >> s;
    if( s == "Monday" ) cout << "5\n";
    if( s == "Tuesday" ) cout << "4\n";
    if( s == "Wednesday" ) cout << "3\n";
    if( s == "Thursday" ) cout << "2\n";
    if( s == "Friday" ) cout << "1\n";
    return 0;
}

B - Split?

要判断局面是不是split,条件有两列没有被全部击倒,但是他们中间有一列被全部击倒。

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

int32_t main() {
    int t[] = { 1,1,2,2,2,1,1};
    int st[] = {3,2,4,1,3,5,0,2,4,6};
    string s;
    cin >> s;
    if( s[0] == '1' )
        cout << "No\n" , exit(0);
    for( int i = 0 ; i <= 9 ; i ++ )
        if( s[i] == '0' ) t[ st[i] ] --;
    for( int i = 0 ; i <= 6 ; i ++ ){
        if( t[i] == 0 ) continue;
        for( int j = i + 1 ; j <= 6 ; j ++ ){
            if( t[j] > 0 ) continue;
            for( int k = j + 1 ; k <= 6 ; k ++ ){
                if( t[k] == 0 ) continue;
                cout << "Yes\n" , exit(0);
            }
        }
    }
    cout << "No\n";
    return 0;
}

C - Index × A

假如当前的区间的是S[l,r],那么下一个区间的是S[l+1,r+1]=S[l,r]-pre[r]+pre[l-1]+m*a[r+1] ,这样先求一下前缀和,然后 \(O(n)\)的求出所有答案就好。

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

const int N = 2e5+5;
int n , m , res , a[N] , b[N] , sum ;

int32_t main() {
    n = read() , m = read() , res = LONG_MIN;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read() , b[i] = b[i-1] + a[i];
    for( int i = 1 ; i < m ; i ++ )
        sum += a[i] * i;
    for( int i = m ; i <= n ; i ++ ){
        sum += m * a[i];
        res = max( res , sum );
        sum -= b[i] - b[i-m];
    }
    cout << res << "\n";
    return 0;
}

D - Index × A(Not Continuous ver.)

与上一题不同的原因是这道题B可以是不连续的。

呢这样化就可以 dp 来做这道题,首先f[i][j],表示前i 个数中选j个的最大值,那么则有f[i][j]=max(f[i-1][j-1]+a[i]*m , f[i-1][j]),然后就是老生常谈的滚动数组加倒序枚举优化一维空间

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

const int N = 2005;
int n , m , a[N] , f[N];

int32_t main() {
    n = read() , m = read() ;
    for( int i = 1 ; i <= m ; i ++ ) f[i] = LONG_MIN;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = min( m , i ) ; j >= 1 ; j -- )
            f[j] = max( f[j] , f[j-1] + a[i] * j );
    cout << f[m] << "\n";
    return 0;
}

E - Erasing Vertices 2

有一个图,每次可以删掉一个点,删掉一个点的代价是这个点所连的边数,删掉一个点后所有与点相连的边也会被删掉。

优先删掉连边少的点,用优先队列来维护一下就好。这里删掉一个点后还要更新所有与这个点相连的点,更新可以把新的状态直接插入优先队列,然后对于每个点只有第一次出队时计算一下共享。

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

const int N = 2e5+5;
int n , m , val[N] , cost[N] , res = LONG_MIN;
bitset<N> vis;
vector<int> e[N];

priority_queue< pair<int,int> > q;

int32_t main() {
    n = read() , m = read();
    for( int i = 1 ; i <= n ; i ++ ) val[i] = read();
    for( int u , v ; m ; m -- ){
        u = read() , v = read();
        e[u].push_back(v) , e[v].push_back(u);
        cost[u] += val[v] , cost[v] += val[u];
    }
    for( int i = 1 ; i <= n ; i ++ ) q.emplace( - cost[i] , i );
    while( q.size() ){
        auto [ c , id ] = q.top(); q.pop() , c = -c ;
        if( vis[id] ) continue;
        vis[id] = 1;
        res = max( res , c );
        for( auto it : e[id] ){
            if( vis[it] ) continue;
            cost[it] -= val[id];
            q.emplace( - cost[it] , it );
        }
    }
    cout << res << "\n";
}
posted @ 2022-09-13 14:39  PHarr  阅读(28)  评论(0编辑  收藏  举报