A. Reverse
题目描述
给一个长度为 n 序列, p 1 , p 2 , … , p n p_1, p_2, \dots, p_n p1,p2,…,pn 。选择两个整数,即一个区间 [ L , R ] [L, R] [L,R] ,对其区间进行反转操作。
要求你找到恰好执行一次反转操作获得的字典最小序列。
序列是一个数组,由 1 到 n 以内的不同数字任意顺序排列组成。例如 [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] 是一个排列,但 [ 1 , 2 , 2 ] [1,2,2] [1,2,2] 和 [ 1 , 3 , 4 ] [1,3,4] [1,3,4] 不是,前者是因为数字重复,后者是因为最大值超过了 n(不在 n 范围内)。
输入描述
输出描述
样例
#1
4
1
1
3
2 1 3
4
1 4 2 3
5
1 2 3 4 5
1
1 2 3
1 2 4 3
1 2 3 4 5
提示
解析
找到第一个 A [ i ] ! = i A[i] != i A[i]!=i 的元素下标为 L,接着找 A [ i ] = = t A[i]==t A[i]==t 的元素下标 R,对这个 [ L , R ] [L, R] [L,R] 区间进行反转即可。
AC Code
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
public static void main(String[] args) throws Exception {
int T = nextInt();
while(T != 0) {
int n = nextInt();
int[] A = new int[n+1];
for(int i = 1; i <= n; i++) A[i] = nextInt();
int L = 0, R = 0;
for(int i = 1; i <= n; i++) {
if(L == 0 && A[i] != i) {
L = i;
continue;
}
if(L != 0 && A[i] == L) {
R = i;
break;
}
}
A = reverse(A, L, R, n);
for(int i = 1; i <= n; i++) out.print(A[i] + " ");
out.println();
T--;
}
out.flush();
}
public static int[] reverse(int[] arr, int start, int end, int n) {
int[] A = new int[n+1];
int cnt = start;
while(start <= end) A[cnt++] = arr[end--];
for(int i = 1; i <= n; i++) {
if(A[i] == 0) A[i] = arr[i];
}
return A;
}
public static int nextInt() throws Exception {
st.nextToken();
return (int) st.nval;
}
}