首页 > 其他 > 详细

九宫重排—题解

时间:2015-03-26 17:39:51      阅读:242      评论:0      收藏:0      [点我收藏+]
历届试题 九宫重排  
时间限制:1.0s   内存限制:256.0MB
      
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
技术分享技术分享
  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22

解题思路:   典型的 bfs , 最坏的情况 9!  最基本的bfs可以过评测。

import java.util.LinkedList;
import java.util.Scanner;



public class Asist
{
	public static final int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
	public static final int move[][] = {{1,0},{-1,0},{0,1},{0,-1}};
	public static final int MAX = 1000000;
	public static  int step = -1;
    
	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		String str1 = sc.nextLine();
		String str2 = sc.nextLine();
	    Node start = new Node();
	    Node end = new Node();
	    for (int i = 0; i < str1.length(); i++)
	    {
	    	if (str1.charAt(i) == '.')
	    	{
	    		start.s = new StringBuffer(str1);
	    		start.s.replace(i, i+1, "0");
	    		start.index = i;
	    		start.step = 0;
	    		start.status = getHash(start.s.toString(), 9);
	    	}
	    	if (str2.charAt(i) == '.')
	    	{
	    		end.s = new StringBuffer(str2);
	    		end.s.replace(i, i+1, "0");
	    		end.index = i;
	    		end.step = 0;
	    		end.status = getHash(end.s.toString(), 9);
	    	}
	    }
	    if (str1.equals(str2)) System.out.println(0);
	    else
	    {
	    	bfs(start, end);
	    	System.out.println(step);
	    }
	}

	private static void bfs(Node start, Node end)
	{
        boolean vis[] = new boolean[MAX];
        LinkedList<Node> list = new LinkedList<Node>();
        Node cur, next;
        cur = getNode(start);
        list.add(cur);
        
        while(!list.isEmpty())
        {
        	cur = list.pop();
            int x = cur.index / 3;
            int y = cur.index % 3;
            for (int i = 0; i < 4; i++)
            {
               int tx = x + move[i][0];
               int ty = y + move[i][1];
               if (tx > 2 || tx < 0 || ty > 2 || ty < 0) continue;
               next = getNode(cur);
               next.index = tx * 3 + ty;
               next.s.replace(cur.index, cur.index+1, cur.s.charAt(next.index)+"");
               next.s.replace(next.index, next.index+1, "0");
               next.step++;
               next.status = getHash(next.s.toString(), 9);
               
               if (next.status == end.status)
               {
            	   step = next.step; return;
               }
               if (!vis[next.status])
               {
            	   vis[next.status] = true;
            	   list.add(next);
               }
            }
        }
	}

	// 对象的拷贝
	private static Node getNode(Node start)
	{
       Node node = new Node();
       node.s = new StringBuffer(start.s.toString());
       node.index = start.index;
       node.step = start.step;
       node.status = start.status;
       return node;
	}

	private static int getHash(String start, int len)
	{
		int sum = 0;
		for (int i = 0; i < len; i++)
		{
           int count = 0;
           for (int j = i + 1; j < len; j++)
             if (start.charAt(i) > start.charAt(j)) count++;
           sum += count * fac[len-i-1];
		}
		return sum+1;
	}    
} 
class Node
{
	StringBuffer s;  // 记录
	int index;       // 空格
	int step;        // 步数
	int status;      // Hash地址
	
}


九宫重排—题解

原文:http://blog.csdn.net/first_sight/article/details/44652251

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!