AtCoder Beginner Contest 325

发布时间 2023-11-14 22:17:35作者: PHarr

A - Takahashi san

#include <bits/stdc++.h>

using namespace std;

#define ll long long

using vi = vector<int>;


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s , t;
    cin >> s >> t;
    cout << s << " san\n";
    return 0;
}

B - World Meeting

//#include <bits/stdc++.h>
#include <iostream>
#include <vector>

using namespace std;

#define ll long long

#define int long long

using vi = vector<int>;


int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vi w( 24 );

    for( int i = 1 , a , b ; i <= n ; i ++ )
        cin >> a >> b , w[b] += a;
    int res = 0;

    for( int l = 0 , r = 8  ; l <= 23 ; l ++ , r ++ ){
        int cnt = 0;
        for ( int i = l ; i <= r ; i ++ )
            cnt += w[ i % 24 ];
        res = max( res , cnt );        
    }

    cout << res << "\n";

    return 0;
}

C - Sensors

#include <bits/stdc++.h>

using namespace std;

#define ll long long

using vi = vector<int>;

int dx[] = {0,0,1,-1,1,1,-1,-1};
int dy[] = {1,-1,0,0,1,-1,1,-1};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int H,W;cin >> H >> W;
    vector<string> s(H);
    for (int i = 0;i < H;i++){
        cin >> s[i];
    }
    vector<vector<int>> vis(H,vector<int>(W));

    int res = 0;
    auto dd = [&](int x,int y)->void{
        queue<pair<int,int>> q;
        q.emplace(x,y);
        while (!q.empty()){
            auto [u,v] = q.front();
            q.pop();
            if (vis[u][v]) continue;
            
            vis[u][v] = 1;
            

            for (int i = 0;i < 8;i++){
                int tx = u + dx[i],ty = v + dy[i];
                if (tx < 0 || tx >= H || ty < 0 || ty >= W || vis[tx][ty]) continue;
                if (s[tx][ty] == '.') continue;
                q.emplace(tx,ty);
            }
        }


    };  

    for (int i = 0;i < H;i++){
        for (int j = 0;j < W;j++){
            if (vis[i][j] || s[i][j] == '.') continue;
            res++;
            dd(i,j);
        }
    }
    cout << res << endl;

    return 0;
}

D - Printing Machine

枚举开始时间,然后把所有已经到达的加入到队列中,然后每次贪心的选择结束时间最少的即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using i32 = int32_t;
using vi = vector<int>;
using pii = pair<int, int>;

const int inf = 1e9, INF = 1e18;
const int mod = 998244353;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vector<pii> p(n);

    for (auto &[x, y]: p) cin >> x >> y;
    p.emplace_back(LLONG_MAX, LLONG_MAX);
    sort(p.begin(), p.end());
    multiset<int> cnt;
    int now = 0, res = 0;
    for (int i = 0; i < n;) {
        now = max(now, p[i].first);
        for (; i < n and p[i].first <= now; i++)
            cnt.insert(p[i].first + p[i].second);
        while (!p.empty() and now < p[i].first) {
            auto it = cnt.lower_bound(now);
            if (it == cnt.end()) break;
            cnt.erase(it);
            now++, res++;
        }
    }
    cout << res << "\n";
    return 0;
}

E - Our clients, please wait a moment

根据汽车火车分别建图,然后求两遍最短路,然后枚举换乘点即可

#include <bits/stdc++.h>

using namespace std;

#define ll long long

#define int long long

using vi = vector<int>;


const int inf = 1e18;


int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n ;
    cin >> n;
    int a , b , c;
    cin >> a >> b >> c;
    vector<vi> g( n+1 , vi( n + 1 ) );
    auto f = g;
    for( int i = 1 ; i <= n ; i ++ ){
        for( int j = 1 , x ; j <= n ; j ++ ){
            cin >> x;
            g[i][j] = x * a;
            f[i][j] = x * b + c ;
        }
    } 

    vi dis( n+1 , inf );
    vi dis1(n + 1,inf);
    dis[1] = 0;
    priority_queue<pair<int,int> , vector<pair<int,int>> , greater<pair<int,int>>> q;
    q.emplace( 0 , 1 );
    vi vis( n + 1 );

    while( !q.empty() ){
        auto [ d , x ] = q.top();
        q.pop();
        if( vis[x] ) continue;
        vis[x] = 1;
        for( int y = 1 ; y <= n ; y ++ ){
            if( dis[y] <= d + g[x][y] ) continue;
            dis[y] = d + g[x][y];
            q.emplace( dis[y] , y );
        }
    }
    
    dis1[n] = 0;
    priority_queue<pair<int,int> , vector<pair<int,int>> , greater<pair<int,int>>> q1;
    q1.emplace( 0 , n );
    vi vis1( n + 1 );

    while( !q1.empty() ){
        auto [ d , x ] = q1.top();
        q1.pop();
        if( vis1[x] ) continue;
        vis1[x] = 1;
        for( int y = 1 ; y <= n ; y ++ ){
            if( dis1[y] <= d + f[x][y] ) continue;
            dis1[y] = d + f[x][y];
            q1.emplace( dis1[y] , y );
        }
    }
    int res = 1e18;
    for (int i = 1;i <= n;i++){
        res = min(res,dis[i] + dis1[i]);
    }
    cout << res << endl;

    return 0;
}

F - Sensor Optimization Dilemma

\(f[i][j]\)表示前\(i\)个部分用了\(j\)个 1 型监控器最少用多少个 2 型监控器。然后枚举一下\(i\)位用了多少个 1 型监控器即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using i32 = int32_t;
using vi = vector<int>;
using pii = pair<int, int>;

const int inf = 1e10, INF = 1e18;
const int mod = 998244353;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vi d(n + 1);
    for (int i = 1; i <= n; i++) cin >> d[i];
    int l1, c1, k1, l2, c2, k2;
    cin >> l1 >> c1 >> k1 >> l2 >> c2 >> k2;
    vector f(n + 1, vi(k1 + 1, 0));
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= k1; j++) {
            f[i][j] = inf;
            for (int k = 0, t; k <= j; k++) {
                t = d[i] - k * l1, t = (t + l2 - 1) / l2;
                f[i][j] = min(f[i][j], f[i - 1][j - k] + t);
                if (t == 0) break;
            }
        }
    }
    int res = INF;
    for (int i = 0; i <= k1; i++)
        if (f[n][i] <= k2) res = min(res, c1 * i + c2 * f[n][i]);
    if( res == INF ) cout << "-1\n";
    else cout << res << "\n";
    return 0;
}

G - offence

一个不太好想的区间 dp

\(f[l][r]\)表示\([l,r]\)经过若干次操作后所能剩下的最短长度,则答案即为\(f[0][n-1]\)

转移首先考虑用两个子区间拼起来的最优解,其次再考虑端点为of的情况。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using i32 = int32_t;
using vi = vector<int>;
using pii = pair<int, int>;

const int inf = 1e10, INF = 1e18;
const int mod = 998244353;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int K;
    string s;
    cin >> s >> K;
    int n = s.size();
    vector f(n + 1, vi(n + 1));
    for (int l = 0; l < n; l++)
        for (int r = 0; r < n; r++)
            f[l][r] = r - l + 1;

    for (int len = 2; len <= n; len++) {
        for (int l = 0, r = len - 1; r < n; l++, r++) {
            if (len == 2) {
                if (s[l] == 'o' and s[r] == 'f') f[l][r] = 0;
            } else {
                for (int k = l; k < r; k++)
                    f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r]);
                if (s[r] == 'f') {
                    for (int k = l; k < r; k++)
                        if (s[k] == 'o' and f[k + 1][r - 1] == 0)
                            f[l][r] = min(f[l][r], (k == 0) ? 0 : f[l][k - 1]);
                }
                if (s[l] == 'o') {
                    for (int k = l + 1; k <= r; k++) {
                        if (s[k] == 'f' and f[l + 1][k - 1] == 0)
                            f[l][r] = min(f[l][r], max(f[k + 1][r] - K, 0ll));
                    }
                }
            }
        }
    }
    cout << f[0][n - 1] << "\n";
    return 0;
}