大致题意:
8*8的棋盘,已知八个皇后的位置,问最少移动多少次,可以让八个皇后不互相攻击。(同行,同列,同斜线视为互相攻击)
思路:
易知八皇后不攻击一共有92种,dfs出这92种,然后对于每种状压求出最少需要移动多少次
复杂度: O( 92 * n * 2 ^ n) (n = 8)
//package ok;
import java.math.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.util.Arrays;
public class Main {
static char mp[][] = new char[10][10];
static pair poi[] = new pair[10];
static int top = 0;
static int path[] = new int[10];
static int dp[] = new int[1 << 8];
static boolean use[] = new boolean[22];
static boolean vis[] = new boolean[123];
static int ans = 0;
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
int T = in.nextInt();
for(int cas = 1; cas <= T; cas ++) {
ans = 1 << 25;
top = 0;
in.nextLine();
for(int i = 0; i < 8;i ++)
mp[i] = in.nextLine().toCharArray();
for(int i = 0; i < 8; i ++){
for(int j = 0; j < 8; j ++)
if(mp[i][j] == 'q') poi[++top] = new pair(i + 1, j + 1);
}
dfs(1);
out.printf("Case %d: %d\n", cas, ans);
out.flush();
}
}
static int cal(pair p, int id) {
if(p.X == id && p.Y == path[id] ) return 0;
if(p.X == id || p.Y == path[id] || p.X + p.Y == id + path[id] || p.X - p.Y == id - path[id] ) return 1;
return 2;
}
static void dfs(int x) {
if( x == 9 ) {
dp[0] = 0;
for(int mask = 1; mask < (1 << 8); mask++) {
dp[mask] = 1 << 25;
int c = 0;
for(int i = 0; i < 8; i ++)
if((mask & (1 << i)) != 0) c ++;
for(int k = 0; k < 8; k ++) {
if((mask & (1 << k)) != 0)
dp[mask] = Math.min(dp[mask], cal(poi[c], k + 1) + dp[mask ^ (1 << k)]);
}
}
ans = Math.min(ans, dp[(1 << 8) - 1]);
return ;
}
for(int y = 1; y <= 8; y ++) {
if(!use[y] && !vis[x + y] && !vis[x -y + 50]) {
use[y] = true;
vis[x + y] = true;
vis[x - y + 50] = true;
path[x] = y;
dfs(x + 1);
vis[x + y] = false;
vis[x - y + 50] = false;
use[y] = false;
}
}
}
public static class pair{
public int X = 0, Y = 0;
pair(int X,int Y){
this.X = X;
this.Y = Y;
}
}
static class Scanner {
BufferedReader br;
StringTokenizer st;
public Scanner(InputStream in) {
br = new BufferedReader(new InputStreamReader(in));
eat("");
}
private void eat(String s) {
st = new StringTokenizer(s);
}
public String nextLine() {
try {
return br.readLine();
} catch (IOException e) {
return null;
}
}
public boolean hasNext() {
while (!st.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
public int[] nextIntArray(int n) {
int[] is = new int[n];
for (int i = 0; i < n; i++) {
is[i] = nextInt();
}
return is;
}
public long[] nextLongArray(int n) {
long[] ls = new long[n];
for (int i = 0; i < n; i++) {
ls[i] = nextLong();
}
return ls;
}
public double[] nextDoubleArray(int n) {
double[] ds = new double[n];
for (int i = 0; i < n; i++) {
ds[i] = nextDouble();
}
return ds;
}
public BigInteger[] nextBigIntegerArray(int n) {
BigInteger[] bs = new BigInteger[n];
for (int i = 0; i < n; i++) {
bs[i] = nextBigInteger();
}
return bs;
}
public int[][] nextIntMatrix(int row, int col) {
int[][] mat = new int[row][];
for (int i = 0; i < row; i++) {
mat[i] = nextIntArray(col);
}
return mat;
}
public long[][] nextLongMatrix(int row, int col) {
long[][] mat = new long[row][];
for (int i = 0; i < row; i++) {
mat[i] = nextLongArray(col);
}
return mat;
}
public double[][] nextDoubleMatrix(int row, int col) {
double[][] mat = new double[row][];
for (int i = 0; i < row; i++) {
mat[i] = nextDoubleArray(col);
}
return mat;
}
public BigInteger[][] nextBigIntegerMatrix(int row, int col) {
BigInteger[][] mat = new BigInteger[row][];
for (int i = 0; i < row; i++) {
mat[i] = nextBigIntegerArray(col);
}
return mat;
}
}
}