Educational Codeforces Round 78 题解

A题

水题,但是我做麻烦了,因为我不知道字符串内部也可以排序,学到一招

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int a[27],b[27];
int main(){
    int t;
    cin>>t;
    while(t--){
        string p;
        string s;
        cin>>p>>s;
        int i;
        int l1=s.size();
        int l2=p.size(); 
        int flag=0;
        if(l1<l2){
            cout<<"NO"<<endl;
            continue;
        }
        for(i=0;i<l1-l2+1;i++){
        memset(a,0,sizeof a);
        memset(b,0,sizeof b);
            flag=0;
            string tmp=s.substr(i,l2);
            int j;
            for(j=0;j<p.size();j++){
                int sign=p[j]-'a';
                a[sign]++;
            }
            for(j=0;j<tmp.size();j++){
            int sign=tmp[j]-'a';
            b[sign]++;} 
            for(j=0;j<26;j++){
             if(a[j]!=b[j]){
                 flag=1;
                 break;
             }}
        if(flag==0){
            cout<<"YES"<<endl;
            break;
        }
    }
    if(flag==1)
    cout<<"NO"<<endl;
}}
View Code

B题

数学题

首先肯定是对差值进行计算,我们自然想要对小的那个一直加逼近大的,所以我们要求取前缀和

我们可以知道,知道前缀和和差值的奇偶性相同就行

因为这样两者相减就是偶数,而我们知道,无论这个差值是多少,我们都可以把他表述为前面若干数的和

这样只需要把前面若干的数给大的,就能抵消,我们注意到变化的数一定是偶数,因为假设我把3给大的,那么小的减3,大的加3,相差是两倍

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int main(){
    int t;
    cin>>t;
    while(t--){
        int s[N]={0};
        int a,b;
        cin>>a>>b;
        if(a>b)
        swap(a,b);
        int sum=b-a;
        int i;
        for(i=1;i<N;i++){
            s[i]=s[i-1]+i;
        }
        if(sum==0)
        cout<<0<<endl;
        else{
            for(i=1;i<N;i++){
                if(s[i]-sum>=0&&(s[i]-sum)%2==0){
                    cout<<i<<endl;
                    break;
                }
            }
        }
    }
}
View Code

C题

本题只要求取前缀和后缀互为相反数的情况中的最小值即可

本题必须要将2转化成-1,因为要使得两个种类的贡献相等才行

tip:利用map

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map> 
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int main(){
    int t;
    cin>>t;
    while(t--){
        int s[N]={0};
        map<int,int> pos;
        int i;
        int n;
        cin>>n;
        pos[0]=0;
        for(i=1;i<=2*n;i++){
            int a;
            cin>>a;
            if(a==2)
            a=-1;
            s[i]=s[i-1]+a;
            if(i<=n)
            pos[s[i]]=i;
        }
        int res=2*n;
        for(i=n;i<=2*n;i++){
            auto it=pos.find(s[i]-s[2*n]);
            if(it!=pos.end())
            res=min(res,i-it->second);
        }
        cout<<res<<endl;
    }
}
View Code

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map> 
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int main(){
    int t;
    cin>>t;
    while(t--){
        int s[N]={0};
        map<int,int> pos;
        int i;
        int n;
        cin>>n;
        pos[0]=0;//一定要注意初始化,也就是左边全吃完的位置是0 
        for(i=1;i<=2*n;i++){
            int a;
            cin>>a;
            if(a==2)//因为两个贡献度相等,所以要相反数 
            a=-1;
            s[i]=s[i-1]+a;
            if(i<=n) //只有小于等于n才会记录下来 
            pos[s[i]]=i;//即使有重复的s[i],我们记录位置靠后的是更好的,所以不用担心覆盖 
        }
        int res=2*n;
        for(i=n;i<=2*n;i++){
            auto it=pos.find(s[i]-s[2*n]);
            if(it!=pos.end())
            res=min(res,i-it->second);
        }
        cout<<res<<endl;
    }
}
加注释版

 

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