Educational Codeforces Round 103 (A-D題解)

昨天打了一下edu103的比賽,場內做出了A,B,C,C一開始沒開long long ,卡了半個小時,D沒時間了,今天補了一下,發現D就是一個簡單dp。
題目鏈接:https://codeforces.com/contest/1476

A. K-divisible Sum

思路:本題就是一個鴿巢定理,推一個公式就行。場內居然wa了3發,做了25分鐘。

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

typedef long long ll;
int _;
ll n, k;

void solve(){
   
   
    cin >> _;
    while(_--){
   
   
        cin >> n >> k;
        if(max(1ll, k/n)*n <= k){
   
   
            cout << k/n + ((k%n==0)?0:1) << "\n";
        }
        else{
   
   
            cout << 1ll + ((n%k==0)?0:1) << "\n";
        }
    }
}

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

    solve();
    return 0;
}

B. Inflation

思路:求一個前綴和,當概率條件不滿足的時候,才需要更新ans。是一個貪心策略,從前往後遍歷一下,即可。要注意,增加ans的時候要上取整。我擔心失精度,沒用double,都用的整數。

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

typedef long long ll;
int _;
int n, k;
ll a[110];
ll sum[110];

void solve(){
   
   
    cin >> _;
    while(_--){
   
   
        cin >> n >> k;
        for(int i = 1; i <= n; i++){
   
   
            cin >> a[i];
        }
        sum[0] = 0;
        for(int i = 1; i <= n; i++){
   
   
            sum[i] = sum[i-1] + a[i];
        }
        ll ans = 0;
        for(int i = 2; i <= n; i++){
   
   
            if(100*a[i] > k*(sum[i-1]+ans)){
   
   
                ll  now = (100*a[i] - k*(sum[i-1]+ans))/k;
                if(100*a[i] > k*(sum[i-1] + ans + now)){
   
   
                    now++;
                }
                ans += now;
            }
        }
        cout << ans << "\n";

    }
}

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

    solve();
    return 0;
}

C. Longest Simple Cycle

思路:求最長的簡單環。如果一個鏈的向後連接點相同,從這裏往後要重新計數。枚舉到一個 c i c_i ci要更新以這裏爲封閉環的情況。碰到必須更新的時候,要注意重新開始。同時,要注意一處細節,如下圖。(開始被卡住是因爲沒開longlong)
在這裏插入圖片描述

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

typedef long long ll;
int _;
int n;
int c[100010];
int a[100010];
int b[100010];
int fen[100010];

void solve(){
   
   
    cin >> _;
    while(_--){
   
   
        cin >> n;
        for(int i = 1; i <= n; i++){
   
   
            cin >> c[i];
        }
        for(int i = 0; i < n; i++){
   
   
            cin >> a[i];
        }
        for(int i = 0; i < n; i++){
   
   
            cin >> b[i];
        }
        for(int i = 0; i <= n; i++){
   
   
            fen[i] = 0;
        }
        for(int i = 1; i <= n; i++){
   
   
            if(a[i] == b[i]){
   
   
                fen[i] = 1;
            }
        }
        a[n] = b[n] = 0;
        fen[n] = 1;
        fen[1] = 0;
        ll ans = 0;
        ll now = 0;
        for(int i = 1; i <= n; i++){
   
   
            if(fen[i]){
   
   
                now += (1ll*c[i] - 1);
                ans = max(now, ans);
                if(i == n){
   
   
                    now = 0;
                }
                else{
   
   
                    now = 2*1ll;}
            }
            else{
   
   
                if(i == 1){
   
   
                    now += abs(1ll*a[i] - 1ll*b[i]);
                }
                else{
   
   
                    now += (1ll*c[i] - 1);
                    ans = max(ans, now);
                    now -= (1ll*c[i] - 1);
                    now += abs(min(1ll*a[i], 1ll*b[i]) - 1) + abs(max(1ll*a[i], 1ll*b[i]) - 1ll*c[i]);
                    now = max(now, abs(1ll*b[i] - 1ll*a[i]));
                }
                now += 2;
            }
        }
        cout << ans << "\n";
    }
}

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

    solve();
    return 0;
}

D. Journey

思路:求從一點開始向右RLRLR,,,的最長距離,向左開始LRLR,,,和自身城市之和就是答案。我們考慮兩個dp,一個維護從一點向右的情況,一個維護從一點向左的情況。因爲每一次更新dp,都要變向,所以方向信息需要記錄,我們把方向狀態開到dp數組裏就行了。

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

int _;
int n;
string s;
int lft[300010][2];
int rht[300010][2];

void solve(){
   
   
    cin >> n;
    cin >> s;
    s = "0" + s;
    for(int i = 0; i <= n; i++){
   
   
        if(i == 0){
   
   
            lft[i][0] = lft[i][1] = 0;
        }
        else{
   
   
            if(s[i] == 'L'){
   
   
                lft[i][0] = lft[i-1][1] + 1;
                lft[i][1] = 0;
            }
            else{
   
   
                lft[i][1] = lft[i-1][0] + 1;
                lft[i][0] = 0;
            }
        }
    }
    for(int i = n; i >= 0; i--){
   
   
        if(i == n){
   
   
            rht[i][0] = rht[i][1] = 0;
        }
        else{
   
   
            if(s[i+1] == 'R'){
   
   
                rht[i][1] = rht[i+1][0] + 1;
                rht[i][0] = 0;
            }
            else{
   
   
                rht[i][0] = rht[i+1][1] + 1;
                rht[i][1] = 0;
            }
        }
    }
    for(int i = 0; i <= n; i++){
   
   
        cout << lft[i][0] + rht[i][1] + 1 << " ";
    }
    cout << "\n";

}

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

    cin >> _;
    while(_--){
   
    solve(); }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章