題目大意:判斷能否找到遞減的子列,將其翻轉後得到的整個數列遞增,只能找一次,最後輸出,如果能還要輸出翻轉的首尾位
置,注意數數組下標,不是首尾的數,當然如果本來數列就遞增,就隨便找個數翻一下。
我的方法是直接模擬,直接從a[0]開始尋找遞減序列,然後判斷遞減序列翻轉後能否構成遞增序列。
#include<stdio.h>
int n,a[100005];
int main()
{
int i,j,h;
bool bo=true;
scanf("%d",&n);
for (i=0;i<n;i++)scanf("%d",&a[i]);
i=0;
while (a[i]<=a[i+1]&&i<n-1) i++; //找到開始遞減的數a[i],即左端點
if (i==n-1) //如果數列一直遞增,就省事多了
{
bo=false;
printf("yes\n1 1");
}
j=i;
while (j<n-1&&a[j]>a[j+1]&&bo) j++; //找到遞減序列的右端點
if (i>0&&a[j]<a[i-1]&&bo) //看看能不能接上,就是遞減子列翻轉後的左端點不能小於前一個數
{
printf("no\n");
bo=false;
}
if (j==n-1&&bo) //判斷後面是否還有數
{
bo=false;
printf("yes\n%d %d\n",i+1,j+1);
}
h=j;
if (h<n-1&&a[h+1]<a[i]&&bo) //看看能不能接上
{
printf("no\n");
bo=false;
}
while (h<n-1&&bo) //如果後面還有數有,看看能不能保證遞增
{
if (a[h]>a[h+1])
{
bo=false;
printf("no\n");
}
h++;
}
if (bo) printf("yes\n%d %d\n",i+1,j+1);
return 0;
}
我的方法有點囉嗦,實際上還有方法,就是現將整個數列按由小到大排序後與原數列比較,
在原數列中分別從最左端、最右端開始找不相等的數,看看這段子列是否滿足遞減。
推薦使用先排序、後比較的方法。