cf补题

Educational Codeforces Round 102 (Rated for Div. 2)

https://codeforces.com/contest/1473

A. Replacing Elements

思路

水题。
如果所有数据都小于等于d则满足要求;如果存在大于d的数据直接判断最小的两个数据相加是否小于等于d即可。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 

const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=5e5+7;
const ll mod=1e9+7;   

int a[107];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
       int n,k,flag=1;
       cin>>n>>k;
       for (int i = 0; i < n; ++i)
       {
            cin>>a[i];
            if(a[i]>k)flag=0;
       }
       sort(a,a+n);
       if(a[0]+a[1]>k&&flag==0)
            cout<<"NO"<<endl; 
       else 
            cout<<"YES"<<endl;
    }
    return 0;
}

B. String LCM

思路

题意是求两个字符串的最小公倍数。
类似于求整数的最小公倍数,将两个字符串依次加上他们本身,直到两个字符串长度相等为止,此时如果两字符串相同则为原字符串的最小共倍数,若不同则不存在。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 

const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=5e5+7;
const ll mod=1e9+7;   

string x,y;

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){
        cin>>x>>y;
        string a=x,b=y;
        while(1){
            if(a.size()==b.size()){
                if(a==b)cout<<a<<endl;
                else cout<<-1<<endl;
                break;
            }else{
                if(a.size()>b.size())b+=y;
                else a+=x;
            }
        }
    }
    return 0;
}

C. No More Inversions

思路

a数组是:1,2,3,…… ,k-1,k,k-1,…… ,k−(n−k)
经过某种奇妙地思考和观察得出:
当n==k时,p数组为:1,2,3,…… ,n
当n !=k时,p数组的后(n-k+1)个元素为:k,k-1,…… ,k−(n−k),剩下的元素为:1,……,2*k-n-1

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 

const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=5e5+7;
const ll mod=1e9+7;   

vector<int>p;

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        if(n==k){
            for (int i = 1; i <= k; ++i)
            {
                cout<<i<<" ";
            }
            cout<<endl;
        }
        else{
            for (int i = 1; i <= 2*k-n-1; ++i)
            {
                cout<<i<<" ";
            }
            for (int i = k, j = 0; j <= n - k; ++j,--i)
            {
                cout<<i<<" ";
            }cout<<endl;
        }

    }
    return 0;
}

D. Program

思路

分析可以得出一个经过字符串操作后的答案应为在此区间中(max-min+1)。
首先从左往右运算将每个位置的值(a[i])求出来,然后从左往右将每个位置的最大值(lmax)最小值(lmin)求出来,再从右往左将每个位置的最大值(rmax)最小值(rmin)求出来。
当忽略了区间[l,r]后,如果此区间后一段内的最大值(rmaxn)减去区间[l,r]的影响(a[r]-a[l-1])后仍然大于l前一段的最大值,则此时最大值应为(rmaxn-(a[r]-a[l-1])),同理可得到最小值。
所以答案应为max(lmax[l-1],rmax[r+1]-(a[r]-a[l-1]))-min(lmin[l-1],rmin[r+1]-(a[r]-a[l-1]))+1.

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 

const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=5e5+7;
const ll mod=1e9+7;   

char s[N];
int a[N],lmax[N],lmin[N],rmax[N],rmin[N];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        cin>>(s+1); 
        //预处理边界值
        rmax[n+1]=-inf;
        rmin[n+1]=inf;

        for (int i = 1; i <= n; ++i)
        {
            if(s[i]=='-')a[i]=a[i-1]-1;
            else a[i]=a[i-1]+1;

            lmin[i]=min(lmin[i-1],a[i]);
            lmax[i]=max(lmax[i-1],a[i]);
        }
        for (int i = n; i > 0; --i)
        {
            rmax[i]=max(rmax[i+1],a[i]);
            rmin[i]=min(rmin[i+1],a[i]);
        }
        while(m--){
            int l,r;
            cin>>l>>r;
            int k=a[r]-a[l-1];
            int maxn=max(lmax[l-1],rmax[r+1]-k);
            int minn=min(lmin[l-1],rmin[r+1]-k);
            cout<<maxn-minn+1<<endl;
        }

    }
    return 0;
}

继续努力!!!

posted @ 2021-01-25 15:11  !^^!  阅读(99)  评论(0)    收藏  举报