Codeforces Round #627 (Div. 3) - 题解与我的分析

这场时间也不错,虽然对于我是unrated,然而为了保持手感还是打了

 

A

给你一个俄罗斯方块的现状态,问你只用1*2(底是1,高是2)的方块能否让所有的方块消掉

很简单吧,如果a[i]跟a[j]相差是1,3,5...这样的奇数,那么怎么填也不行

如果所有的a[i]与a[j],a[i] - a[j]的绝对值对2取模是0,那么就是yes,否则是no

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

int a[maxn];

int main(){
    int T;
    cin >> T;
    while(T--){
        int n;
        bool good = true;
        cin >> n;
        for(int i = 0; i < n; ++i){
            cin >> a[i];
            for(int j = i - 1; j >= 0; --j){
                if(abs(a[i] - a[j]) % 2 == 1){
                    good = false;
                }
            }
        }
        cout << (good ? "YES" : "NO") << endl;
    }
    return 0;
}

 

B

对于一个数列来说,问你是否有长大于等于3的回文数列,例如[1,3,1]或者[1,2,2,1]这样的

结论异常的简单,无论对于长是奇数还是偶数的回文数列,一定有相隔超过1,数字相等的两个位置。

只要有这样的位置,那么就是yes,否则就是no

用map的线性算法或者暴力的平方复杂度都可以

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

int a[maxn];

int main(){
    int T;
    cin >> T;
    while(T--){
        int n;
        cin >> n;
        bool good = false;
        for(int i = 0; i < n; ++i){
            cin >> a[i];
            for(int j = i - 2; j >= 0; --j){
                if(a[i] == a[j]){
                    good = true;
                }
            }
        }
        cout << (good ? "YES" : "NO") << endl;
    }
    return 0;
}

 

C

青蛙在0位置要到n+1的位置,0到n+1之间有长为n的,只包含L或R的字符串,L说明可以往左跳,R说明可以向右跳,每次最多跳t的长度

问你保证能跳到n+1的位置上的情况下,t的最小值

分析下,如果你跳到L位置,最终还是会跳到更近的R位置,所以无论怎么样,我们跳到L位置上的长度>=我们不跳到L位置上的长度

那么我们只考虑跳到R位置上的长度,吧0跟n+1也想成R位置,算出相近的R,位置之差的最大值即可

#include<bits/stdc++.h>
#define LL long long
#define maxn 200010
using namespace std;
     
int a[maxn];
     
int main(){
    int T;
    cin >> T;
    while(T--){
        string s;
        cin >> s;
        int n = s.size();
        int now = -1, ans = 0;
        for(int i = 0; i < n; ++i){
            if(s[i] == 'R'){
                ans = max(i - now, ans);
                now = i;
            }
        }
        ans = max(n - now, ans);
        cout << ans << endl;
    }
    return 0;
}

 

D

有n节课,每节课都有a[i]和b[i]属性,问你满足i>j,a[i]+a[j]>b[i]+b[j]的组有多少

a[i] - b[i] > -(a[j] - b[j]),我们存一下-(a[i] - b[i]),然后排序,每个i二分找比多少-(a[i] - b[i])大即可

注意如果a[i]-b[i]>0的话,会把本身也算进去一遍,这个时候减去1就行了

#include<bits/stdc++.h>
#define LL long long
#define maxn 200010
using namespace std;
     
int a[maxn], b[maxn], c[maxn];
     
int main(){
    int n;
    cin >> n;
    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){
        c[i] = b[i] - a[i];
    }
    LL ans = 0;
    sort(c, c + n);
    for(int i = 0; i < n; ++i){
        int now = lower_bound(c, c + n, a[i] - b[i]) - c;
        if(a[i] - b[i] > 0){
            ans--;
        }
        ans = ans + now;
    }
    cout << ans / 2 << endl;
    return 0;
}

 

E

一天有h小时,主人公要睡n次觉,一次可以睡a[i]小时或者a[i]-1个小时,醒了马上就要睡下一觉直到睡完n次,如果睡觉起来的时候时间(如果时间大于一天就要对h取模)在l到r之间,那么这一觉就是good,加一分,问你睡完这n次,最多得多少分

显然局部最优解无法推出全局最优解,我们考虑dp来储存状态

dp[i][j]表示睡完第i次时,有j次睡了a[i]-1个小时,i-j次睡了a[i]个小时的最大得分

转移方程就很好想了,从i-1天的j-1跟j状态转移即可

答案就是i从0-n,dp[n][i]的最大值

#include<bits/stdc++.h>
#define LL long long
#define maxn 2010
using namespace std;
     
int dp[maxn][maxn];
     
int main(){
    int n, h, l, r, t;
    LL sum = 0;
    cin >> n >> h >> l >> r;
    int ans = 0;
    for(int i = 1; i <= n; ++i){
        cin >> t;
        sum = sum + t;
        for(int j = 0; j <= i; ++j){
            int good = (l <= ((sum - j) % h) && ((sum - j) % h) <= r) ? 1 : 0;
            //cout << ((sum - j) % n) << " " << good << endl;
            if(j == 0){
                dp[i][j] = dp[i - 1][j] + good;
            } 
            else if(j == i){
                dp[i][j] = dp[i - 1][j - 1] + good;
            }
            else{
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + good;
            }
            ans = max(ans, dp[i][j]);
        }
    }
    cout << ans << endl;
    return 0;
}

 

F题👴偷个小懒,嘻嘻

 

整体来看这次还是比较简单的,偏向思维的题多一些

 

posted @ 2020-03-13 14:43  Stein_Gate_Amadeus  阅读(301)  评论(0)    收藏  举报