一道中文题,应该比较好理解了吧~~~
这道用搜索,就是一个一个湖泊过去,搜索这些湖泊与哪些湖泊相连,动态更新邻接矩阵以及各个湖泊剩余与其有水路相连的未确定湖泊数(这里用brr数组)。而且,对于第i个湖泊,因为已经搜索了前面i-1个湖泊,这i-1个湖泊与该湖泊的水路相连状态也就确定了。所以就直接从第i+1个湖泊搜下去,搜brr[i]个。
相当于平常的求n个数中取k个的组合方案问题多了一层的搜索,代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
public class Main {
/**
* @param args
*/
static int n, t;
static int arr[], brr[];
static boolean bo[][];
static boolean flag;
private static void dfs(int step, int k, int nown) {
if ((step == n) && (brr[n] == 0)) {
flag = true;
return;
}
if (k == brr[step] + 1) {
dfs(step + 1, 1, step + 2);
return;
}
for (int i = nown; i <= n - brr[step] + k; i++)
if (brr[i] > 0) {
bo[step][i] = true;
brr[i]--;
dfs(step, k + 1, i + 1);
if (flag)
return;
brr[i]++;
bo[step][i] = false;
}
}
private static void deal() {
brr = arr.clone();
flag = false;
bo = new boolean[n + 1][n + 1];
dfs(1, 1, 2);
if (!flag)
System.out.println("NO");
else {
System.out.println("YES");
for (int i = 1; i <= n; i++)
for (int j = 1; j < i; j++)
bo[i][j] = bo[j][i];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
if (bo[i][j])
System.out.print("1 ");
else
System.out.print("0 ");
System.out.println();
}
}
System.out.println();
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Reader.init(System.in);
t = Reader.nextInt();
for (int casenum = 1; casenum <= t; casenum++) {
n = Reader.nextInt();
arr = new int[n + 1];
for (int i = 1; i <= n; i++)
arr[i] = Reader.nextInt();
deal();
}
}
}