Codeforces Round #767 (Div. 2) A~D题解

比赛通道

A.Download More RAM

题意:

T组数据:

​ 给n组a和b,给一个初始值k。

​ 如果a[i]<=k,那么k加上b[i]

​ 输出k的最大值

思路:

用a当关键字从小到大排序,一个for循环跑一遍一直累加b,知道k<a[i]为止

时间复杂度:\(O(n)\)

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
#define int long long
int T,n,k;
struct yzh
{
    int a,b;
}cf[10010];
bool cmp(yzh a,yzh b){
    return a.a<b.a;
}
signed main(){
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;++i){
            scanf("%lld",&cf[i].a);
        }
        for(int i=1;i<=n;++i){
            scanf("%lld",&cf[i].b);
        }
        sort(cf+1,cf+n+1,cmp);
        for(int i=1;i<=n;++i){
            if(k>=cf[i].a){
                k+=cf[i].b;
            }
            else{
                break;
            }
        }
        printf("%lld\n",k);
    }
    return 0;
}

B.GCD Arrays

题意:

T组数据,每组数据给l,r,k。

定义数组a的元素为l~r的整数,要求k次删除操作使得a中所有元素的最大公约数>1。

思路:

思考怎么删除是最优的,我们发现a中的元素一定是连续的整数,若让最大公约数>1的话只留下偶数(即最大公约数为2)是最优解。

这是因为偶数相隔一个数,且GCD一定大于等于2,而要求更高的GCD间隔一定大于一。所以去除奇数是最少方案.

复杂度:\(O(1)\)

注:数据中如果有l=r且l>1那么直接输出YES

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
#define int long long
int T,l,r,k;
signed main(){
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld%lld",&l,&r,&k);
        int t=(r-l+1)/2;
        if(r%2==1&&t*2!=(r-l+1)) ++t;//若l到r正整数个数为奇数,那么就要进行特判
        if(r==l&&r>1){
            puts("YES");
            continue;
        }
        if(t>k){
            puts("NO");
        }
        else{
            puts("YES");
        }
    }
    return 0;
}

C.Meximum Array

题意:

给定一个由n个非负整数组成的数组a,Mihai希望创建一个新的数组b,该数组的形成方式如下:

当a不为空时有一下操作:

选择一个整数k(1≤K≤|a|)。

将数组a的前k个数字的MEX附加到数组b的末尾,并从数组a中删除它们,从而移动a中其余数字的位置。

要求输出字典序最大的b串。

其中,一组非负整数的MEX是不在该集合的非负整数的最小值。例如,MEX({1,2,3}) =0 and MEX({0,1,2,4,5}) =3。

思路:

建一个数组vis记录每个数出现的次数。注:这个vis在代码中定义的是b,题目中的b数组在题目中定义的为ans

然后对vis下标从0到往后找,知道找到vis[t]为0时,这就是b数组的第一个数(因为t为最小出现次数为0的数,所以t是生成MEX的极限,不可能有比t更大的MEX)。

然后取k,要求尽量k尽量小,我们就定义vist数组用来标记删除点,一个for循环进行删除前k个值的操作,若小于t的vis都已经进行过删除标记,那么就停止删除,这样就可以达到k的尽量小。

至于复杂度,各位也能发现这是一个NP问题,是没有多项式复杂度的,但是也能过,如果哪位大佬能用P来求解,那么欢迎留言。

代码:

#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int t,n,a[200010],b[200010],m,ans[200010];
bool vis[200010];
signed main(){
    scanf("%d",&t);
    while(t--){
        memset(b,0,sizeof(b));
        m=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
            b[a[i]]++;
        }
        int id=0;
        while(id<n){
            int t=0;
            while(b[t]){
                ++t;
            }
            // cout<<"::"<<t<<endl;
            if(!t){
                ans[++m]=0;
                id++;
                continue;
            }
            else{
                ans[++m]=t;
            }
            int it=t;
            memset(vis,false,sizeof(vis));
            while(it){
                ++id;
                if(!vis[a[id]]&&a[id]<t){
                    it--;
                    vis[a[id]]=true;
                }
                b[a[id]]--;
            }
        }
        printf("%d\n",m);
        for(int i=1;i<=m;++i){
            printf("%d ",ans[i]);
        }
        puts("");
    }
    return 0;
}

D.Peculiar Movie Preferences

题意:

有n个字符串(长度不超过3),要求删除若干个字符串(可以为0),剩下的串按照顺序拼起来,能否组成一个回文串。

思路:

如果一个串自身就是一个回文那么直接输出YES

然后就是分多种情况讨论:

(AB)(BA)

(ABC)(BA)

(AB)(CBA)

(ABC)(CBA)

这几种情况进行判断即可。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
using namespace std;
int T,n;
string s[100010];
bool flag[100010];
set<string> st;
signed main(){
    scanf("%d",&T);
    while(T--){
        st.clear();
        memset(flag,false,sizeof(flag));
        scanf("%d",&n);
        int flt=false;
        for(int i=1;i<=n;++i){
            cin>>s[i];
            int len=s[i].length();
            if(s[i][0]==s[i][len-1]&&s[i][1]==s[i][len-2]){//自身为回文
                flag[i]=true;
                flt=true;
            }
            if(len==2){
                string t = "";
                t = t + s[i][1] ;
                t = t + s[i][0];
                if (st.count(t)) flt = true;
            }
            if(len==3){
                string t = "";
                t = t + s[i][2];
                t = t + s[i][1];
                if (st.count(t)) flt = true;
                t = t + s[i][0];
                if (st.count(t)) flt = true;
            }
            st.insert(s[i]);
        }
        st.clear();
        for(int i=n;i>=1;--i){//倒着找
            int len=s[i].length();
            if(len==3){
                string t = "";
                t = t+s[i][1];
                t = t+s[i][0];
                if (st.count(t)) {
                    flt = true;
                    break;
                }
            }
            st.insert(s[i]);
        }
        if(flt){
            puts("YES");
        }
        else{
            puts("NO");
        }
    }
    return 0;
}
posted @ 2022-01-23 10:47  SZBR_yzh  阅读(100)  评论(1编辑  收藏  举报