Codeforces Round #619 题解

A题 

签到题,只要从头枚举即可,注意如果AB中的字符相等,那么C也要和他们相等,因为C每次都要和一个进行兑换

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector> 
using namespace std;
typedef long long ll;
const int N=5e5+10;
int main(){    
    int t;
    cin>>t;
    while(t--){
        string a;
        string b;
        string c;
        cin>>a>>b>>c;
        int i;
        int tt=0;
        for(i=0;i<a.size();i++){
            if(a[i]==b[i]&&c[i]==a[i])
            continue;
            if(c[i]==a[i]||c[i]==b[i])
            continue;
            break;
        } 
        if(i==a.size())
        cout<<"YES"<<endl;
        else
        cout<<"NO"<<endl;
    }
    return 0;
}
 
View Code

 

B题

我们可以这么想,一定是找到最大值和最小值的中间值,才能使答案最小,所以我们可以用一个vector存满足条件的值排序,也就是这个值不是-1的情况(除了下面列举的一种特殊情况)

但是本题有两个坑点

1.如果相邻两个都不是-1,那么我们要考虑最后的答案是不是这两个数的差,因为比如 是40 -1 50 100 -1 101,这样的话其实50才是答案,这情况题目有给提示。

2.我们加入vector中的数,两边至少有一个是-1,否则不用加入这个数,因为 我们要填的是-1的位置,连续三个数都不是-1,那么中间这个数是不用加入vector的

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector> 
using namespace std;
typedef long long ll;
const int N=5e5+10;
vector<int> num; 
int a[N];
int main(){    
    int t;
    cin>>t;
    while(t--){
        num.clear();
        int n;
        int i;
        cin>>n;
        int tmp1=0;
        int tmp2=0;
        for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
        a[0]=a[1];
        a[n+1]=a[n];
        for(i=1;i<=n;i++){
            if(a[i]!=-1&&(a[i-1]==-1||a[i+1]==-1))
            num.push_back(a[i]);
            if(a[i]!=-1&&a[i-1]!=-1&&i>=2){
                tmp1=max(tmp1,abs(a[i]-a[i-1]));
            }
        }
        if(num.size()==0){
            cout<<0<<" "<<0<<endl;
            continue;
        }
        sort(num.begin(),num.end());
        num.erase(unique(num.begin(),num.end()),num.end());
        int m=num.size()-1;
        int sign=num[0]+num[m]>>1;
        int res=max(abs(sign-num[0]),abs(sign-num[m]));
        if(res<tmp1){
            res=tmp1;
        }
        cout<<res<<" "<<sign<<endl;
    }
    return 0;
}
View Code

C题 

反向思考,我们要求子串是1的最多,也就是要求子串是0的最少,我们知道一个公式,那就是子串的个数为(n)*(n+1)/2,所以这题抽象为将n-m个0分为m+1组,相当用每个1分割一组,这样就能最大限度地分割

而且每组0中尽量都是平均分的个数,但是显然我们存在(n-m)%(m+1)不等于0的情况,所以剩下的余数平均分给前面几组,这道题其实是贪心的题目

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector> 
using namespace std;
typedef long long ll;
const int N=5e5+10;
void solve(){
    int n,m;
    scanf("%d%d",&n,&m);
    ll ans = (ll)n * (ll)(n + 1) / 2LL;
    int z = n - m;
    int k = z / (m + 1);
    ans -= (ll)(m + 1) * (ll)k * (ll)(k + 1) / 2LL;
    ans -= (ll)(z % (m + 1)) * (ll)(k + 1);
    printf("%lld\n",ans);
}
 int main(){
    int t;
    cin >> t;
    while(t--){
        solve();
    }    
    return 0;
}
View Code

 

posted @ 2020-02-14 11:27  朝暮不思  阅读(152)  评论(0编辑  收藏  举报