A. Reverse
题解
题意:给定一个n个元素的全排列,在区间[l, r]中进行一次反转操作后,能够得到的字典序最小的排列。
我们首先知道最小的字典序的排列就是标准排列:1,2,... ,n
直接与给定的排列一一比较,第一个不相符的元素,向数组后面找当前位置的元素,然后反转。
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
ios :: sync_with_stdio(false);
int T; cin >> T;
while (T -- )
{
int n; cin >> n;
vector <int> a(n + 10);
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 1; i <= n; i ++ )
if (a[i] != i)
{
for (int j = i + 1; j <= n; j ++ )
if (a[j] == i)
{
reverse (a.begin() + i, a.begin() + j + 1);
break;
}
break;
}
for (int i = 1; i <= n; i ++ ) cout << a[i] << " ";
cout << endl;
}
return 0;
}
B. Odd Swap Sort
题解
题意需要我们对一个长度n的数组进行操作:如果(a[i] + a[i + 1]) % 2 != 0,就可以交换这两个数;
问:能不能在任意次数操作后,使得原数组非降序排列
首先,解读操作,两和是奇数才可以交换,那么两个奇偶性相同的数就不可以交换,而我们的目标是达到一个非降序的数组。
所以,如果i < j && a[i] > a[j] && a[i] % 2 == a[j] % 2, 那么我们就可以确定答案是NO了。
同时,我们可以将一个数组分为两个来看,一个存放奇数,另一个存放偶数,只要任意的一个数组内,存在降序的情况,答案就是NO,否则就是YES。
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define endl '\n'
int main ()
{
#ifdef LOCAL
freopen ("data.in", "r", stdin);
freopen ("data.out", "w", stdout);
#endif
ios :: sync_with_stdio(false);
int T; cin >> T;
while (T -- )
{
int n; cin >> n;
vector <int> evn(n);
vector <int> odd(n);
int sign[2] = {1, 1}, x;
for (int i = 1; i <= n; i ++ ){
cin >> x;
if (x % 2 == 0) evn.push_back(x);
else odd.push_back(x);
}
for (int i = 0; i < evn.size() - 1; i ++ )
if (evn[i] > evn[i + 1]) {sign[0] = 0; break;}
for (int i = 0; i < odd.size() - 1; i ++ )
if (odd[i] > odd[i + 1]) {sign[1] = 0; break;}
if (sign[0] && sign[1]) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}