Codeforces Round #410 (Div. 2) 题解 【ABCD】

A

题意:问你恰好修改一个字符,能不能使得字符串变成回文串

题解:显然直接for一遍,如果长度为偶数,那么不一样的必须是1个;如果长度为奇数,那么不一样的也可以是0个

#include<bits/stdc++.h>
using namespace std;

string s;
int main(){
    cin>>s;
    int tmp = 0;
    for(int i=0;i<s.size();i++){
        if(s[i]!=s[s.size()-1-i])
            tmp++;
    }
    if(tmp>2||(tmp==0&&s.size()%2==0)){
        cout<<"NO"<<endl;
    }else{
        cout<<"YES"<<endl;
    }
}

B - Mike and strings

题意:你可以把开头的字符移动到最后去,然后问你最少一共移动多少次,可以使得所有字符都变得一模一样。

题解:显然就直接暴力就好了嘛,数据范围很小。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;

string s[maxn];
int n;
int main(){
    cin>>n;
    int ans = 1e5+7;
    for(int i=0;i<n;i++)
        cin>>s[i];
    for(int i=0;i<s[0].size();i++){
        int tmp = i;
        string s2 = s[0].substr(i,s[0].size()-i)+s[0].substr(0,i);
        for(int j=1;j<n;j++){
            int flag = 0;
            for(int k=0;k<s[j].size();k++){
                string s3 = s[j].substr(k,s[j].size()-k)+s[j].substr(0,k);
                if(s3==s2){
                    flag = 1;
                    tmp+=k;
                    break;
                }
            }   
            if(flag == 0){
                return puts("-1");
            }
        }
        ans = min(ans,tmp);
    }
    cout<<ans<<endl;
}

C. Mike and gcd problem

题意:你可以操作(i,i+1)使得,a[i],a[i+1]变成a[i]-a[i+1]和a[i]+a[i+1],问你最少操作多少次,可以使得所有数的gcd>1

题解:如果一开始不行的话,那么我们就让gcd等于2就好了,那么就让所有数都变成偶数,如果两个数都是奇数,那么一次就变成了。如果是奇数和偶数,那么得两次。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n,a[maxn];
int gcd(int a,int b){
    if(b==0)return a;
    return gcd(b,a%b);
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        cin>>a[i];
    int tmp = 0;
    for(int i=0;i<n;i++){
        tmp = gcd(a[i],tmp);
    }
    if(tmp>1){
        cout<<"YES"<<endl;
        cout<<"0"<<endl;
        return 0;
    }
    int ans = 0;
    for(int i=0;i<n;i++){
        if(a[i]%2==1){
            if(a[i+1]%2==1){
                ans++;
            }else
                ans+=2;
            a[i]=0,a[i+1]=0;
        }
    }
    cout<<"YES"<<endl;
    cout<<ans<<endl;
}

D. Mike and distribution

题意:让你选出最多n/2+1个数,出来要求2A[i]和2B[i]都大于数组的和。

题解:显然我们先排序,然后我们两两对比,我们当然是选择第二大的就好了。证明很简单,这里略过。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
pair<int,pair<int,int> >a[maxn];
int n;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i].first),a[i].second.second = i+1;
    for(int i=0;i<n;i++)
        scanf("%d",&a[i].second.first);
    cout<<n/2+1<<endl;
    sort(a,a+n);
    cout<<a[n-1].second.second<<" ";
    for(int i=n-2;i>=0;i-=2){
        if(i==0){
            cout<<a[i].second.second<<endl;
        }else{
            if(a[i].second.first>a[i-1].second.first)
                cout<<a[i].second.second<<" ";
            else
                cout<<a[i-1].second.second<<" ";
        }
    }
}
posted @ 2017-04-28 19:32  qscqesze  阅读(293)  评论(0编辑  收藏  举报