题目链接:
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);
}
}
}
}