hdu1043

康托展开 + 离线bfs(打表) ,菜的不说了,wa了一页( javaio真杀死我)

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main{
	
	static  int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};	// 阶乘
	static int cantor(int [] a, int n)
	{
		int x = 0;
		for (int i = 0; i < n; ++i) {
			int smaller = 0;  // 在当前位之后小于其的个数
			for (int j = i + 1; j < n; ++j) {
				if (a[j] < a[i])
					smaller++;
			}
			x += FAC[n - i - 1] * smaller; // 康托展开累加
		}
		return x+1;  // 康托展开值
	}
	
	static String[] solution;
	static int[] vis;
	static int[] xx= {-1,1,0,0};
	static int[] yy= {0,0,-1,1};

	
	static class Node{
		int[] a;
		int pos;
	}
	
	static String [] ss  = {"d","u","r","l"};

	static void bfs() {
		vis=new int [370000];
		solution = new String[370000];
		Queue<Node> q=  new LinkedList<Node>();
		Node node = new Node();
		node.a = new int[] {1,2,3,4,5,6,7,8,0};
		node.pos=8;
		solution[cantor(node.a,9)]="";
		q.add(node);   
		while(!q.isEmpty()) {
			Node top = q.poll();
			for(int i=0;i<4;i++) {
				        
				int x2 = top.pos/3 + xx[i];
				int y2 = top.pos%3 + yy[i];
				int newpos = x2*3+y2;   
				
				if(x2>-1 &&x2<3 && y2>-1 && y2<3) {
					int[] a2 = new int [9];
					a2 = Arrays.copyOf(top.a, top.a.length);
					
					a2[top.pos] = a2[newpos]; //交换指定位置
					a2[newpos] = 0;
					
					Node newnode = new Node();//构建个节点
					newnode.a = a2;
					newnode.pos=newpos;
					
					int kt1 = cantor(top.a,9);  //旧状态和新状态的cantor值
					int kt2 =cantor(a2 ,9);
					
					if( vis[kt2]==0) {
						vis[kt2] = 1 ;
						solution[kt2]="";
						solution[kt2]=solution[kt1]+ss[i]; 
						q.add(newnode);
					}
				}
			}
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		bfs();
		while(sc.hasNext()) {
			int[]  aa = new int[9];
			
			int con = 0;
			while(con!=9) {	
				 String c = sc.nextLine();
				 for(int i=0;i<c.length();i++) {
					 if(c.charAt(i)=='x') {
						 aa[con++]=0;
					 }else if(c.charAt(i)>='0' && c.charAt(i)<='8'){
						 aa[con++]=c.charAt(i)-'0';
					 }
				 }
			}
			
			int temp = cantor(aa,9);
			
			if(vis[temp] ==1 ) {
				String res = solution[temp];	
				System.out.println(new StringBuilder(res).reverse().toString());
			}else 
				System.out.println("unsolvable");
			
			
			
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值