Codeforces Round #771 (Div. 2) ABC

Problem - A - Codeforces

题目大意:给定一个长度为n的数组a,选择两个整数下标l,r进行reverse操作:p1,p2,···pl−1,pr,pr−1,…pl,pr+1,pr+2…,pn。输出按字典序排列的最小序列。

input

4
1
1
3
2 1 3
4
1 4 2 3
5
1 2 3 4 5

output

1 
1 2 3 
1 2 4 3 
1 2 3 4 5 

直接找不在位置上的最小数字即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<map>
using namespace std;
int a[200200];
int main()
{
    //cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int minn=n,idx=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            if(a[i]!=i&&i<minn) minn=i;
            if(a[i]==minn) idx=i;
        }
        //cout<<minn<<" "<<idx<<endl;
        for(int i=1;i<minn;i++)
            cout<<i<<" ";
        for(int i=idx;i>=minn;i--)
            cout<<a[i]<<" ";
        for(int i=idx+1;i<=n;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    return 0;
}

Problem - B - Codeforces

题目大意:给定一个长度为n的数组a,如果a[i]+a[i+1]是奇数的话,那么它们两就可以换位置,问是否可以使用此操作多次按非降序(不严格升序)对其进行排序。可以Yes,不能No。

input

4
4
1 6 31 14
2
4 2
5
2 9 6 7 10
3
6 6 6

output

Yes
No
No
Yes

这题我当时写的代码被叉了呜呜呜,while过于暴力,卡时间了,以后还是得注意时间些!

结论题:仔细想因为它们的交换原则就是一步一步的走,假设一个数组中7在前,5在后,我需要把5挪到7前面去,那这怎么可能呢?一定会有7 5交锋的时候,这个时候也就是移不动了的时候。再假设4在前,2在后,无论中间有多少奇数都可以把4 2交锋,它们这个时候也动不了了。但是如果7 4那么它们就可以移动。说明这题只需要分别对比奇偶,如果它两都成非降序就ok

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<map>
using namespace std;
int a[200200];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        int ji=0,ou=0;
        bool flag=true;
        for(int i=1;i<=n;i++)
        {
            if(a[i]&1)
            {
                if(a[i]<ji)
                {
                    flag=false;
                    break;
                }
                else ji=a[i];
            }
            else
            {
                if(a[i]<ou)
                {
                    flag=false;
                    break;
                }
                else ou=a[i];
            }
        }
        if(flag==true) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}

Problem - C - Codeforces

题目大意:给定一个长度为n的数组a,构造一个无向图:在顶点i,j之间添加一条边,使得i<j当且仅当ai>aj。问此图中连接的组件的数量。

input

6
3
1 2 3
5
2 1 4 3 5
6
6 1 4 2 5 3
1
1
6
3 2 1 6 5 4
5
3 1 5 2 4

output

3
3
1
1
2
1

因为ai>aj所以找到每一个区间的最大值就能知道初步的组件数量,又由于别的部分的小值也能联通进入前面的max,所以直接转变思考方向:就是指找前缀最大值等于长度的个数。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<map>
using namespace std;
int a[200200];
int main()
{
    //cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        int sum=0,maxn=0;
        for(int i=1;i<=n;i++)
        {
            maxn=max(maxn,a[i]);
            if(i==maxn) sum++;
            //cout<<maxn<<" "<<sum<<endl;
        }
        cout<<sum<<endl;
    }
    return 0;
}

ABC全结论题!唔,还是我太菜了。

任重而道远!继续冲!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vijurria

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值