链接:
https://codeforces.com/problemset/problem/451/B
题意
给你一个长度为n的数组,判断是否可以通过翻转某一段的方式使变化后的数组是从小到大排序的递增数组。(如果可以输出yes,区间左值和区间右值(从1开始),不行输出no)
1 ≤ n ≤ 105
a[1], a[2], …, a[n] (1 ≤ a[i] ≤ 109)
Example
input
3
3 2 1
output
yes
1 3
input
4
2 1 3 4
output
yes
1 2
input
4
3 1 2 4
output
no
input
2
1 2
output
yes
1 1
解析
这题可以在输入数组的时候复制一个原数组,然后将原数组从小到大排序,然后遍历比较两个数组,第一个不一样的位置是区间左值,最后一个是区间右值。最后遍历区间里,变化后的数组和原数组是否成对称(翻转)关系,即对比在区间[l, r]内,满足:原来数组[l + i] = 变化数组[r - i],如果中间出现不一样的,就说明不行。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int q[N], tem[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> q[i];
tem[i] = q[i];
}
sort(tem + 1, tem + n + 1);
int l = 0, r = 0;
for (int i = 1; i <= n; i++)
{
if (q[i] != tem[i])
{
l = i;
int j = n;
while (q[j] == tem[j])
{
j--;
}
r = j;
break;
}
}
if (l == 0) l = 1;
if (r == 0) r = 1;
for (int i = l, j = r; i < r; i++, j--)
{
if (q[i] != tem[j])
{
cout << "no";
return 0;
}
}
cout << "yes" << endl << l << ' ' << r;
return 0;
}