Codeforces Round #617 (Div. 3)题解

CF老是打不开,所以鸽了好久…

决定有空搭个梯子,到时候会写写流程。

C.Yet Another Walking Robot
题意:给你一个字符串只含有LRUD表示左右上下移动。问你从原点开始,通过一系列的动作到达另外一个点,你需要从字符串中找到一个最短的字串使得执行字串动作后位置不变。比如说LR、UD、LUDR都是符合要求的。

思路:开始没有想到思路。就硬生生到字符串中找字串然后暴力判断是否对称类似的,然后tle了。正确的做法是,把走过的点都用map存下来,如果发现重复的点,即回到了那个点,那么从那个点到现在这个点就算没有动了,判断一下取最小值就行。
可能解释得不是很清楚,看代码很清晰。

#include 
using namespace std;


int main(){
    int n;
    cin>>n;
    while(n--){
        int t;
        cin>>t;
        string s;
        cin>>s;
        map<pair<int,int>,int>mp;
        pair<int,int>pr(0,0);
        mp[pr]=0;
        int l=-1,r=t+1;
        for(int i=0;i<t;i++){
            if(s[i]=='L'){
                pr.first--;
            }
            else if(s[i]=='R'){
                pr.first++;
            }
            else if(s[i]=='U'){
                pr.second++;
            }
            else if(s[i]=='D'){
                pr.second--;
            }
            if(mp.count(pr)){
                if(i-mp[pr]<r-l){
                    r=i;
                    l=mp[pr];
                }
            }
            mp[pr]=i+1; //这一步到该点,下一步开始算作重复部分,即左端点
        }
        if(l==-1){
            cout<<-1<<endl;
        }
        else
        cout<<l+1<<" "<<r+1<<endl;
    }


    return 0;
}

D. Fight with Monstersshui
题意: 你和对手一起打怪。有n个怪,你攻击力为a,对手攻击力为b,每次都是你先打,只有最后一击才算击杀,你杀了就加一分,问你最多能得多少分,而且你有k个技能,一次能跳过对手的一次攻击机会。
思路:说实话这题不难,赛后直接1A了,赛中卡死在了C题实在可惜。
因为只算最后一杀,所以可以先把怪物的血进行取模运算,前面几次攻击没有意义。虽然你可以用技能跳过,但是并不是对方的每次攻击都要跳过,比如说你的攻击力是1,对手的攻击力是10,面对血量9的怪物,你在此时消耗过多的技能是不对的。随意sort一下然后从小开始用技能就行了。感觉比C题简单。

#include 
using namespace std;
const int MAX=2e5+5;
int p[MAX];
int main (){
    int n,a,b,k;
    cin>>n>>a>>b>>k;
    for(int i=0;i<n;i++){
        cin>>p[i];
        p[i]%=(a+b);
        if(p[i]==0){
            p[i]=(a+b);
        }
    }
    sort(p,p+n);
    int sum=0;
    for(int i=0;i<n;i++){
            while(1){
                if(p[i]<=a){
                    sum++;
                    break;
                }
                else {
                    if(k>0){
                        k--;
                        p[i]-=a;
                    }
                    else {
                        break;
                    }
                }

            }
    }
    cout<<sum<<endl;
    return 0;
}

E1.String Colorishuing (easy version)
题意大概就是给字符串染色,不同的颜色换位置,问你最后能不能换成一个不下降的顺序,比如说aaabbcbb,我们按照01011011染色就可以称为aaabbbbc。

思路:因为只需要染两种颜色,所以比较简单,就是找两个不下降序列。在第一个序列里就填0,第二个序列里就填1.因为只有不同的颜色能交换位置。所以属于同一个序列的字符是换不了位置的。如果这两个序列不是不下降或者说存在第三个,都是无法换的。

#include 
using namespace std;
int main(){
    int n;
    cin>>n;
    string s;
    cin>>s;
    char flag1='a',flag2='a';
    for(int i=0;i<n;i++){
        if(s[i]>=flag1){
            flag1=s[i];
            s[i]='0';
        }
        else if(s[i]>=flag2){
            flag2=s[i];
            s[i]='1';
        }
        else {
            cout<<"NO"<<endl;
            return 0;
        }
    }
    cout<<"YES"<<endl;
    cout<<s<<endl;


    return 0;
}

E2.看我另外一遍博客 传送门

你可能感兴趣的:(cf题解)