题目描述 给定一个长度为n的整数数组a,元素均不相同,问数组是否存在这样一个片段,只将该片段翻转就可以使整个数组升序排列。其中数组片段[l,r]表示序列a[l], a[l+1], ..., a[r]。原始数组为
a[1], a[2], ..., a[l-2], a[l-1], a[l], a[l+1], ..., a[r-1], a[r], a[r+1], a[r+2], ..., a[n-1], a[n],
将片段[l,r]反序后的数组是
a[1], a[2], ..., a[l-2], a[l-1], a[r], a[r-1], ..., a[l+1], a[l], a[r+1], a[r+2], ..., a[n-1], a[n]。
输入
第一行数据是一个整数:n (1≤n≤105),表示数组长度。
第二行数据是n个整数a[1], a[2], ..., a[n] (1≤a[i]≤109)。
|
|
输出
输出“yes”,如果存在;否则输出“no”,不用输出引号。
|
|
| |
不限于递增递减,分情况考虑
//思路:递增递减 该数组必须满足 有1-2个单调转折点,转折点处数据能接上
//↑↓,!(↓↑↓),↓↑, ↑↓↑
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int *p;
int num;
int i;
int j=0;
int turn[2] = {0, 0};//转折点坐标值
int type1, type2=0, last, now;
scanf("%d", &num);
p = (int*)malloc(num*sizeof(int));
for (i = 0; i < num; ++i)
{
scanf("%d", p++);
}
p-=num;
if(*(p) < *(p+1))
type1 = last = 1;
else
type1 = last = 0;
for (i = 1; i < num-1; ++i)
{
if(*(p+i) < *(p+i+1))
now = 1;
else
now = 0;
if(now != last)
{
type2++;
if(type2 > 2)
{
printf("no\n");
return 0;
}
turn[j++] = i+1; //记录转折点数据
last = now;
}
}
if(type2 == 0)
printf("yes\n");
else if(type2 == 1)
{
if(type1 == 1) //起始递增
{
if((*p > *(p+turn[0])) || (*(p+num-1) > *(p+turn[0]-2)))
printf("yes\n");
else
printf("no\n");
}
else //起始递减
{
if((*(p+num-1) < *(p+turn[0]-2)) || (*p < *(p+turn[0])))
printf("yes\n");
else
printf("no\n");
}
}
else //type2 == 2 两次转折
{
if(((type1 == 1) && (*(p+turn[1]-1) > *(p+turn[0]-2)) && (*(p+turn[0]-1) < *(p+turn[1])))
|| ((type1 == 0) && (*(p+turn[1]-1) < *(p+turn[0]-2)) && (*(p+turn[0]-1) > *(p+turn[1]))))
printf("yes\n");
else
printf("no\n");
}
free(p);
return 0;
}