import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
static int n;
static int number = 0;
static int[] arr = new int[20000];
static boolean[] st = new boolean[20000];
static int s;
static int count = 0;
static boolean judge = true;
static boolean return0 = false;
static int[] a = new int[20000];
public static void main(String[] args) throws Exception {
Read sc = new Read();
n = sc.nextInt();
s = sc.nextInt();
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
}
dfs(1);
}
public static int dfs(int x) {
if (return0) {
return 0;
}
if (x > n) {
count++;
for (int i = 1; i <= n; i++) {
if (a[i] != arr[i])
judge = false;
}
if (judge) {
number = count;
judge = false;
}
if (count == s + number) {
return0 = true;
for (int i = 1; i <= n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
return 0;
}
return 0;
}
for (int i = 1; i <= n; i++) {
if (count == 0) {
i = a[x];
}
if (!st[i]) {
st[i] = true;
arr[x] = i;
dfs(x + 1);
st[i] = false;
arr[x] = 0;
}
}
return 0;
}
}
class Read {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public int nextInt() throws Exception {
st.nextToken();
return (int) st.nval;
}
public long nextLong() throws Exception {
st.nextToken();
return (long) st.nval;
}
}
在这段代码中,if(count == 0) i = a[x] 的作用是确保第一个位置上的手指值与输入数组中对应位置的值相匹配。如果我们去掉这段代码,那么第一个位置上的手指值将会根据循环中的变量 i 迭代取值,而不是根据输入数组确定。
假设输入数组 a = {3, 1, 2, 4, 5},如果我们去掉 if(count == 0) i = a[x] 这段代码,那么程序将会按照以下步骤执行:
- 第一个位置的手指值 i 可能的取值为 1、2、3、4、5。
- 假设首先是 i = 1,在处理第一个位置时,我们将手指值设为 1。
- 然后,递归调用 dfs 函数处理下一个位置。此时 count 的值为 1。
- 下一个位置的处理仍然会进行循环,手指值的可能取值同样为 1、2、3、4、5。这导致第二个位置上的手指值也有可能为 1。
- 然后,递归调用 dfs 函数处理下一个位置。此时 count 的值为 2。
- 这样的循环过程会一直进行下去,导致程序生成了错误的手指排列。
而如果我们保留 if(count == 0) i = a[x] 这段代码,将根据输入数组确定第一个位置上的手指值为 3。这样,在递归调用 dfs 函数处理下一个位置时,就不会再出现第一个位置上的手指值为 1 的情况。
这段代码中的 if(count == 0) i = a[x]
只在初始情况下执行一次,目的是将第一个位置上的手指值与输入数组中对应位置的值相匹配。
在回溯算法中,我们通常使用一个计数器(例如 count
)来追踪当前处理的手指位置。当 count
的值为 0 时,说明我们正在处理第一个位置上的手指值,此时我们通过 if(count == 0) i = a[x]
将第一个位置上的手指值设定为输入数组中对应位置的值。
在后续的递归调用中,count
的值将不再为 0,因此这段代码将不会再执行,保持当前处理的手指值不变。这样可以确保程序按照正确的顺序生成所有可能的手指排列。
所以,即使 count
只有在初始时为 0,这段代码仍然是必要的,它确保了第一个位置上的手指值正确地与输入数组匹配。