算法设计与分析: 6-21 图形变换问题

6-21 图形变换问题


问题描述

给定 2 个 4 × 4 方格阵列组成的图形 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

王晓东《计算机算法设计与分析》

猜你喜欢

转载自blog.csdn.net/IOIO_/article/details/81200478