Codeforces Round #659 (Div. 2)A~C题解

发布于 2020-07-25  0 次阅读


A.Common Prefixes

思路:

在这里插入图片描述

直接看官方题解吧,直接建立一个200长的字符串,然后反转每次输入的数组的位置,原因稍微想一下就知道了

AC Code:

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=109;
int n, a;
string s(200, 'a');
void solve(){
    cin>>n;
    cout<<s<<endl;
    for(int i=0; i<n; i++){
        cin>>a;
        if(s[a]=='a')   s[a]='b';
        else    s[a]='a';
        cout<<s<<endl;
    }
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

B1. Koa and the Beach (Easy Version)

B2. Koa and the Beach (Hard Version)

思路:

按照正常人思维走就行了,
1、最开始在涨潮到最高走(边落潮边走)
2、到达最高潮的都不会溺水的位置(安全点)就等他涨到满潮(后面又可以边落潮边走)
3、可能溺水的情况就尽快去到下一个完全安全的位置,也就是快速度过两个安全点中间的部分。

AC Code:

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=109;
int n, k, l ,d;
int water, p, i, flag;       //water:水面高度(-为落潮,+为涨潮
void solve(){
    cin>>n>>k>>l;
    water=-k;                   //潮涨到最高,准备落潮
    flag=1;
    for(i=1; i<=n; i++){
        cin>>d;
        p=l-d;
        if(p<0) {flag=0; break;}            //正常水位都会溺水,活不过去了,死定了
        if(p>=k)    water=-k;               //潮涨满了都淹不死,就等到潮涨满落潮时走(-k状态
        else    water=max(water+1, -p);     //一、最开始高过l,就等潮落到刚好淹不死的情况下到达该位置;二、可以直接走,水必须落潮1
        if(water>p) {flag=0; break;}        //每次水位变化后检查当前水位是否可以使之溺水
    }
    for(; i<n; i++)    cin>>d;         //溺水了break后继续把后面的d输入完
    if(flag)    cout<<"YES"<<endl;
    else        cout<<"NO"<<endl;
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

C. String Transformation 1

思路:

1、首先判断是否存在a中字符已经大于相应位置的b的字符(因为这种情况下不可能增大a变成b,输出-1)
2、因为可以从a中选择所有相同的字符进行改变,所有肯定从最小的字符开始选择并且进行改变
3、贪心策略:
每次变化的时候将所有字符变成当前可变的最小字符
未变成到b中相应位置的a更新后继续变换,知道匹配b成功

AC Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
// #define TDS_ACM_LOCAL
const int N=1e5 + 9;
vector<int>v[25];
string a, b;
int n, ans;
void solve(){
    ans=0;
    for(int i=0; i<19; i++) v[i].clear();   //初始化vector
    cin>>n>>a>>b;
    for(int i=0; i<n; i++){                 //将相应位置a最后变成的b存下
        if(a[i]>b[i])   {cout<<"-1"<<endl; return ;}
        else if(a[i]<b[i])  v[a[i]-'a'].push_back(b[i]-'a');
    }
    for(int i=0; i<19; i++){
        sort(v[i].begin(), v[i].end());
        if(v[i].size()!=0){
            for(int j=1; j<v[i].size(); j++)        //遍历a可以变成的b,并且让a变成可以变成的b中的最小值
                if(v[i][j]!=v[i][0])    v[v[i][0]].push_back(v[i][j]);  //将a变成最小值后仍然需要继续改变的值更新
            ans++;                  //每次群体的变化操作次数加1
        }
    }   
    cout<<ans<<endl;
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}


平平无奇的在校大学生