Codeforces Round #650 (Div. 3)(A-F1)题解

A. Short Substrings

题解:按题意模拟即可

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int main()
{
    int t;
    cin>>t;
    while(t--){
        cin>>s;
        if(s.size()==2){
            cout<<s<<endl;
            continue ;
        }
        cout<<s[0];
        for(int i=1;i<s.size()-1;i+=2){
            cout<<s[i];
        }
        cout<<s[s.size()-1]<<endl;
    }
    return 0;
}

B - Even Array

判断一下不符合条件的情况,看看两种不符合条件的情况是否相等,如果相等即可调换,不相等输出-1.

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int cnt=0,cnt1=0;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            if(a[i]%2==0&&i%2!=0) cnt++;
            if(a[i]%2!=0&&i%2==0) cnt1++;
        }
        if(cnt!=cnt1) cout<<-1<<endl;
        else cout<<cnt<<endl;
 
    }
    return 0;
}

C - Social Distance

题解:我们把有1的地方扩散一下,也就是假设第i个地方是1,那么i到i+k和i+k是都不可以做人的,那么我们把不能做人的地方用#打个标记即可,然后寻找有0的地方,并且没次在0的地方坐下一个客人,位置要向前移动k个。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int main()
{
    int t,k,n;
    cin>>t;
    while(t--){
        cin>>n>>k;
        cin>>s;
        for(int i=0;i<n;i++){
            if(s[i]=='1'){
                for(int j=max(0,i-k);j<=min(n-1,i+k);j++){
                    s[j]='#';
 
                }
            }
        }
        int ans=0;
        for(int i=0;i<n;i++){
            if(s[i]=='0'){
                ans++;
                i+=k;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

D - Task On The Board

感觉这个题目涉及了一点点思维,但是模拟起来细节有点多。
思路:对于0的位置,字母一定是最大的,对于字母第二大的元素,他只会受第一大字母的影响,同理,第三大字母只受比他大的字母的影响。
所以我们遍历每个位置看看,某个字母是否符合这个位置的b数组的大小
还有一个小细节,就是我们需要看看这个字母最多能匹配多少个位置,如果位置的个数大于当前字母的个数,说明这个字母不可以用。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;

char ans[maxn];
string s;
int visited[maxn],cnt[maxn];
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        cin>>s;
        int n,z=0;
        cin>>n;
        memset(cnt,0,sizeof(cnt));
        memset(visited,false,sizeof(visited));
        char imax='a';
        for(int i=0;i<s.size();i++){
            cnt[s[i]-'a']++;
            if(imax<s[i]) imax=s[i];
        }
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        for(int i=0;i<n;i++){
            if(!a[i])  visited[i]=true,z++;
        }
        for(int i=25;i>=0;i--){
            if(cnt[i]>=z){
                for(int j=0;j<n;j++) if(!a[j]) ans[j]=i+'a';
                cnt[i]=0;
                break;
            }
            cnt[i]=0;
        }
        for(int i=25;i>=0;i--){
            if(cnt[i]!=0){
                int x=0;
                for(int j=0;j<n;j++){
                    if(!visited[j]){
                        int sum=0;
                        for(int k=0;k<n;k++){
                            if(visited[k]&&ans[k]>i+'a'){
                                sum+=abs(j-k);
                            }
                        }
                        if(sum==a[j]){
                            visited[j]=true;
                            x++;
                            ans[j]=i+'a';
                        }
                    }
                }
                if(x>cnt[i]){
                    for(int j=0;j<n;j++){
                        if(ans[j]==i+'a') visited[j]=false;
                    }
                }
            }
        }
        for(int i=0;i<n;i++) printf("%c",ans[i]);
        printf("\n");
    }
    return 0;
}

E - Necklace Assembly

做的时候也想到过跟因子有关,可惜太菜了,没想出来。
参考了这个大佬的思路:https://www.bilibili.com/video/BV1xT4y1J7yd?p=2

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int cnt[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        cin>>s;
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<s.size();i++){
            cnt[s[i]-'a']++;
        }
        vector<int> v;
        for(int i=1;i<=k;i++){
            if(k%i==0) v.push_back(i);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(auto x : v){
                if(x%i==0){
                    ans=max(ans,i);
                }
                if(i%x==0){
                    int dx=i/x;
                    int cnt1=0;
                    for(int j=0;j<26;j++){
                        cnt1+=cnt[j]/dx;
                    }
                    if(cnt1>=x){
                        ans=max(ans,i);
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

F1 - Flying Sort (Easy Version)

本题数据较大,所以要事先离散化一下,为什么可以这样离散化,是因为条件给出了每个数字最多出现一次,所以我们把他按照由小到大的顺序分别代表1-n的数字。
在用dp求出最长上升子序列即可。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
int dp[maxn];
int a[maxn],b[maxn];
map<int,int> mp;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        memset(dp,0,sizeof(dp));
        mp.clear();
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
            mp[b[i]]=i;
        }
        sort(b,b+n);
        for(int i=0;i<n;i++){
            a[mp[b[i]]]=i;
        }
        int imax=1;
        for(int i=0;i<n;i++){
            dp[a[i]]=dp[a[i]-1]+1;
            imax=max(imax,dp[a[i]]);
        }
        cout<<n-imax<<endl;
    }
    return 0;
}

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