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)
Educational Codeforces Round 103 (A-D题解)_第1张图片

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

你可能感兴趣的:(CF,算法,动态规划)