Codeforces Round #649 (Div.2)题解

A - XXXXX

题意:这个题让你找从开头或者是结尾去掉最少几个数以后总和是不能整除给定的x
思路:如果这个序列总和可以整除给定的x的话,那么我们只要找到一个数可以不被x整除,把他从序列中取出,那么序列中剩余的总和也就不能被整除了。
分别从前从后开始搜索即可:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        ll ans=0;
        for(int i=0;i<n;i++) scanf("%d",&a[i]),ans+=a[i];
        int pos1=n-1,pos2=0;
        if(ans%k==0){
            for(int i=0;i<n;i++){
                if(a[i]%k!=0&&a[i]!=0){
                    pos1=i;
                    break;
                }
            }
            for(int i=n-1;i>=0;i--){
                if(a[i]%k!=0&&a[i]!=0){
                    pos2=i;
                    break;
                }
            }
            //cout<<pos1<<" "<<pos2<<endl;
            int ans=min(pos1+1,n-pos2);
            if(ans==n) cout<<-1<<endl;
            else
            printf("%d\n",n-ans);
        }
        else cout<<n<<endl;
    }
    return 0;
}

B - Most socially-distanced subsequence

题意:让你从序列中找出某些元素,让其|a1-a2|+|a2-a3|+|a3-a4|+…+|an-1-an|的值最大化,输出你找出对的这些元素**(元素相对位置不可以变化)。**
题解:我们我们可以把这个序列中的所有元素抽象成一个函数图像,那么我们找出这个(函数)上的所有极值点即可,必定极大值和极小值是交替的。我们让他们彼此相减即可。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int a[maxn];
int rem[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        int cnt=1;
        rem[0]=a[0];
        for(int i=1;i<n-1;i++){
            if(a[i]>a[i-1]&&a[i]>a[i+1]) rem[cnt++]=a[i];
            else if(a[i]<a[i-1]&&a[i]<a[i+1]) rem[cnt++]=a[i];
        }
        if(rem[cnt-1]!=a[n-1]) rem[cnt++]=a[n-1];
        int ans=0;
        //for(int i=0;i<cnt-1;i++) ans+=abs(rem[i]-rem[i+1]);
        printf("%d\n",cnt);
        for(int i=0;i<cnt;i++){
            printf("%d ",rem[i]);
        }
        printf("\n");
    }
    return 0;
}

C - Ehab and Prefix MEXs

在这里插入图片描述题意。。。不多哔哔了,描述不清
mex(S)的值为集合S中没有出现过的最小自然数。例如,mex({1,2}) = 0、mex({0,1,2,3}) = 4
题解:我们从哪里下手呢?
首先我们可以看到a[i]严格小于等于i
再者保证a是一个不下降序列

因为所有的数小于1e6所以我们不妨开一个数组来记录一下出现过的数字
用visited数组记录出现过的数字,若出现过标记为true,没有出现过则为false
类似于我图片上的样子
在这里插入图片描述
代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1e6+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;

int a[maxn];
bool visited[maxn];

int main()
{
	 int n;
	 cin>>n;
	 memset(visited,false,sizeof(visited));
	 for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        visited[a[i]]=true;
	 }
	 int pos=0;
	 for(int i=1;i<=n;i++){
        if(a[i]!=a[i-1]&&i!=1) printf("%d ",a[i-1]);
        else{
            while(visited[pos]==true) pos++;
            printf("%d ",pos++);
        }
	 }
	 return 0;
}

猜你喜欢

转载自blog.csdn.net/xxxxxiao123/article/details/106743156
今日推荐