九宫格旋转问题。

九宫格旋转问题。_第1张图片

 

 

 

 

 

手动测试页面:http://coolpeng.duapp.com/test/temp1/test.html

 

 

程序实现方案

 

 

九宫格旋转问题。_第2张图片

 

 

 

九宫格的每一个状态,都可以看做是图中的一个节点。

总共有9*8*7*6*5*4*3*2*1=362880个节点

每个节点周围都有八个路径可以选择。

这样就变成了一个无向图

然后,使用广度优先遍历。

贪心算法,如果遍历过了之后,不再遍历。

计算出答案,只需要1秒钟。

 

九宫格旋转问题。_第3张图片

 

 

 

 

代码

 

 

package com.tms.cell;

/**
 * Created by 栾海鹏 on 2016/1/28.
 */
public class Node {
    private int[][] status;
    private boolean hasVisited = false;
    private String fromPath;
    private int mmHashCode;


    public Node(int[][] status) {
        this.setStatus(status);
    }


    public int getMmHashCode() {
        return mmHashCode;
    }

    public void setMmHashCode(int mmHashCode) {
        this.mmHashCode = mmHashCode;
    }

    public boolean isHasVisited() {
        return hasVisited;
    }

    public void setHasVisited(boolean hasVisited) {
        this.hasVisited = hasVisited;
    }

    public int[][] getStatus() {
        return status;
    }

    public static int calculateHashCode(int[][] status){
        int m = 1;
        int mmHashCode = 0;
        for (int[] s : status) {
            for (int x : s) {
                mmHashCode = mmHashCode + x * m;
                m = m * 10;
            }
        }

        return mmHashCode;
    }

    public void setStatus(int[][] status) {
        this.mmHashCode = calculateHashCode(status);
        this.status = status;
    }

    public String getFromPath() {
        return fromPath;
    }

    public void setFromPath(String fromPath) {
        this.fromPath = fromPath;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Node)) return false;

        Node node = (Node) o;

        if (mmHashCode != node.mmHashCode) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return mmHashCode;
    }
}

 

 

 

 

package com.tms.cell;

/**
 * Created by 栾海鹏 on 2016/1/28.
 */
public class PathDirection {
    private int x;
    private int y;
    private boolean isR;
    private String name;
    public PathDirection(int x, int y,boolean isR,String name) {
        this.x = x;
        this.y = y;
        this.isR = isR;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int [][] getNextNodeStatus(int mm[][]){
        if (isR){
            return this.getNextNodeStatus_R(mm);
        }
        return this.getNextNodeStatus_r(mm);
    }

    private void arrayCopy(int s[][],int t[][]){
        for (int i = 0 ;i<3;i++){
            for (int j=0;j<3;j++){
                t[i][j] = s[i][j];
            }
        }
    }


    /**
     * 逆时针
     * @param mm
     * @return
     */
    private int[][] getNextNodeStatus_R(int mm[][]) {
        int[][] d = new int[3][3];

        arrayCopy(mm,d);

        int temp = d[x][y];
        d[x][y] = d[x][y + 1];
        d[x][y + 1] = d[x + 1][y + 1];
        d[x + 1][y + 1] = d[x + 1][y + 0];
        d[x + 1][y + 0] = temp;
        return d;
    }


    /**
     * 顺时针
     * @param mm
     * @return
     */
    private int[][] getNextNodeStatus_r(int mm[][]) {
        int[][] d = new int[3][3];
        arrayCopy(mm,d);

        int temp = d[x][y];
        d[x][y] = d[x+1][y+0];
        d[x+1][y+0] = d[x+1][y+1];
        d[x+1][y+1] = d[x+0][y+1];
        d[x+0][y+1] = temp;

        return d;
    }


}

 

 

package com.tms.cell;

import java.util.*;

/**
 * Created by 栾海鹏 on 2016/1/28.
 */
public class Main {

    private static Map<Node, Node> NODE_MAP = new HashMap<Node, Node>();

    private static List<PathDirection> directionList = new ArrayList<PathDirection>(4);

    private static LinkedList<Node> waitVisitNodeList = new LinkedList<Node>();


    private static Node targetNode = new Node(new int[][]{
            {9, 4, 7},
            {8, 5, 2},
            {3, 6, 1}
    });



//    private static Node targetNode = new Node(new int[][]{
//            {2, 5, 3},
//            {1, 4, 6},
//            {7, 8, 9}
//    });


//    private static Node targetNode = new Node(new int[][]{
//            {4, 6, 1},
//            {9, 2, 3},
//            {5, 7, 8}
//    });


//        private static Node targetNode = new Node(new int[][]{
//            {1, 6, 2},
//            {4, 3, 5},
//            {9, 7, 8}
//        });


//        private static Node targetNode = new Node(new int[][]{
//            {6, 7, 3},
//            {9, 1, 4},
//            {8, 2, 5}
//        });


    static {

        directionList.add(new PathDirection(0, 0, true, "R1"));
        directionList.add(new PathDirection(0, 1, true, "R2"));
        directionList.add(new PathDirection(1, 0, true, "R3"));
        directionList.add(new PathDirection(1, 1, true, "R4"));

        directionList.add(new PathDirection(0, 0, false, "r1"));
        directionList.add(new PathDirection(0, 1, false, "r2"));
        directionList.add(new PathDirection(1, 0, false, "r3"));
        directionList.add(new PathDirection(1, 1, false, "r4"));
    }

    public static void main(String[] args) {
        Node startNode = new Node(new int[][]{
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        });
        startNode.setFromPath("");
        waitVisitNodeList.add(startNode);
        long a= System.currentTimeMillis();
        int count = visitMap();
        long b = System.currentTimeMillis();
        System.out.println("耗时MS:"+(b-a));
        System.out.println("探索次数:"+count);
    }

    private static int visitMap() {
        int count = 0;
        while (true) {
            Node node = waitVisitNodeList.pollFirst();
            if (node != null && !node.isHasVisited()) {
                boolean hasFound = visitNode(node);
                count++;
                if (hasFound) {
                    return count;
                }
            }

            if (node == null) {
                return count;
            }

        }
    }

    private static boolean visitNode(Node currentNode) {
        if (currentNode.equals(targetNode)) {
            //打印出答案
            System.out.println("找到路径:"+currentNode.getFromPath());
            return true;
        }
        currentNode.setHasVisited(true);

        for (PathDirection direction : directionList) {
            int[][] nextStatus = direction.getNextNodeStatus(currentNode.getStatus());

            Node nextNode = new Node(nextStatus);
            nextNode.setFromPath(currentNode.getFromPath() + direction.getName());

            Node node = NODE_MAP.get(nextNode);
            if (node == null) {
                NODE_MAP.put(nextNode, nextNode);
                waitVisitNodeList.add(nextNode);
            }

        }
        return false;
    }
}

 

你可能感兴趣的:(九宫格旋转问题。)