排序检测

题目链接:

http://47.96.162.210/problem/1059

题面:

在这里插入图片描述
在这里插入图片描述

思路:

根据题目意思我们是先需要找到翻转区间的左右边界,我们可以先把一开始的数组顺序存储到另外一个数组,然后将原数组进行sort排序,之后先正序判断最早出现不同的先定义为翻转区间的左边界,然后在逆序判断最早出现不同的定义为翻转区间的右边界,初始我们都把左右边界定义为0,当没有出现给不同的情况则就是完全相同,则就是当左右边界相同的情况,然后其他的情况,我们就判断前一个数字减还一个数是否出现给小于0的情况,如果小于0则就是正序,就不能进行翻转,所以一旦出现小于0的情况就进行标记,输出no,从来没有被标记的就证明可以进行翻转,我们就直接输出左右边界。

参考代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,i,left=0,right=0,flag=0;
        scanf("%d",&n);
        int a[n+10];
        int b[n+10];
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];//把原来的a[i]的排列顺序先存储到b数组里面
        }
        sort(a+1,a+1+n);//对a数组进行从小到大的排序
        for(i=1;i<=n;i++)//先找到翻转区间的左边界
        {
            if(a[i]!=b[i])
            {
                left=i;
                break;
            }
        }
        for(i=n;i>=1;i--)//再找翻转区间的右边界
        {
            if(a[i]!=b[i])
            {
                right=i;
                break;
            }
        }
        if(left==right)//如果左边界和右边界相同就证明一开始就是正常排序
        {
            printf("YES\n");
            printf("1 1\n");
        }
        else
        {
            for(i=left;i<=right-1;i++)
            {
                if(b[i]-b[i+1]<0)//判断在翻转区间里面的数组是否满足前一个数字大于后一个数字,如果出现前一个数字小于后一个数字,就证明不能进行翻转来得到从小到大的排列顺序,进行标记
                {
                    flag=1;
                    break;
                }
            }
            if(flag==1)
            {
                printf("NO\n");
            }
            else
            {
                printf("YES\n");
                printf("%d %d\n",left,right);
            }
        }
    }
}

发布了55 篇原创文章 · 获赞 12 · 访问量 8966

猜你喜欢

转载自blog.csdn.net/qq_45740533/article/details/103650849