6-21 图形变换问题
问题描述
给定 2 个 方格阵列组成的图形 A 和 B,每个方格的颜色为黑色或白色。方格阵列中有公共边的方格称为相邻方格。图形变换问题的每一步变换可以交换相邻方格的颜色。试 设计一个算法,计算最少需要多少步变换,才能将图形 A 变换为图形 B。
对于给定的 2 个方格阵列,编程计算将图形 A 变换为图形 B 的最少变换次数。
数据输入:
前 4 行是图形 A 的方格阵列,后 4 行是图形 B 的方格阵列。0 表示白色,1 表示黑色。
Java
package Chapter6FenZhiXianJieFa;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class TuXingBianHuan {
private static final int MaxSize = 1<<16;
private static int sour,dest;
private static int[] a = new int[MaxSize];
private static int[] b = new int[MaxSize];
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
init(input);
if(fifobb()){
System.out.println(a[dest]);
output(dest);
}else
System.out.println("No Solution!");
}
}
private static void init(Scanner input){
int i;
String[] src = new String[4];
String[] des = new String[4];
char[] srcChars = new char[16];
char[] desChars = new char[16];
for(i=0; i<4; i++){
src[i] = input.next();
System.arraycopy(src[i].toCharArray(),0,srcChars,4*i,4);
}
for(i=0; i<4; i++){
des[i] = input.next();
System.arraycopy(des[i].toCharArray(),0,desChars,4*i,4);
}
for(sour=i=0; i<16; i++) sour|=(srcChars[i]-'0')<<i;
for(dest=i=0; i<16; i++) dest|=(desChars[i]-'0')<<i;
}
private static boolean fifobb(){
Queue<Integer> Q = new LinkedList<>();
int E = 0;
for(int i=1; i<MaxSize; i++) a[i]=-1;
a[sour]=0;
Q.add(sour);
while (!Q.isEmpty()){
E = Q.poll();
for(int j=0,mode=3; j<16; j++,mode<<=1)
if(j%4!=3 && (((E&mode)>>j)==1 || ((E&mode)>>j)==2)){
int N = E^mode;
if(a[N] == -1){
a[N] = a[E]+1;
b[N] = j;
Q.add(N);
}
}
for(int j=0,mode=17; j<12; j++,mode<<=1)
if(((E&mode)>>j)==1 || ((E&mode)>>j)==16){
int N = E^mode;
if(a[N] == -1){
a[N] = a[E]+1;
b[N] = -j-1;
Q.add(N);
}
}
if(a[dest] != -1) return true;
}
return false;
}
private static void output(int E){
if(E == sour) return;
int last = E;
if(b[E] >= 0) last^=3<<b[E];
else last^=17<<(-b[E]-1);
output(last);
if(b[E] >= 0){
System.out.print(b[E]/4+1);
System.out.print(b[E]%4+1);
System.out.print(b[E]/4+1);
System.out.print(b[E]%4+2);
System.out.println();
}
else {
System.out.print((-b[E]-1)/4+1);
System.out.print((-b[E]-1)%4+1);
System.out.print((-b[E]-1)/4+2);
System.out.print((-b[E]-1)%4+1);
System.out.println();
}
}
}
Input & Output
1010
0100
0010
1010
0110
0001
0010
1010
3
1112
2223
2324
1010
0101
1010
0101
0101
1010
0101
1010
8
1112
1314
2122
2324
3132
3334
4142
4344
1111
0000
1111
0000
0000
1111
0000
1111
8
1121
1222
1323
1424
3141
3242
3343
3444
Reference
王晓东《计算机算法设计与分析》