参考http://blog.csdn.net/helloworld10086/article/details/41853389

package com.EightNumber.view;
import java.util.*; public class EightNumPath {
final static int dx[] = {-1, 1, 0, 0};
final static int dy[] = { 0, 0,-1, 1};
final static String dir = "UDLR";
static int maxstate = 400000;
static int [][]st = new int[maxstate][9];
static int []goal = {1,2,3,4,5,6,7,8,0};
static int []dist = new int[maxstate];
static int []fa = new int[maxstate];
static int []move = new int[maxstate];
static boolean []vis = new boolean[maxstate];
static int []fact = new int[9];
static StringBuffer path;
public static boolean isok(int []a) {
int sum=0;
for(int i=0; i < 9; i++)
for(int j=i+1; j < 9; j++)
if(a[j] != 0 && a[i] != 0 && a[i] > a[j])
sum++;
if(sum % 2 == 0) {
return true;
}
return false;
}
private static void init_lookup_table() {
fact[0] = 1;
for(int i = 1; i < 9; i++) {
fact[i] = fact[i-1] * i;
}
Arrays.fill(vis, false);
}
private static boolean try_to_insert(int s) {
int code = 0;
for(int i = 0; i < 9; i++) {
int cnt = 0;
for(int j = i+1; j < 9; j++) {
if(st[s][j] < st[s][i]) {
cnt++;
}
}
code += fact[8-i] * cnt;
}
if(vis[code]) {
return false;
}
return vis[code] = true;
} private static void print_path(int cur) {
while(cur != 1) {
path.insert(0,dir.charAt(move[cur]));
cur = fa[cur];
}
}
private static int bfs() {
init_lookup_table();
int front = 1 , rear = 2;
try_to_insert(front);
while(front < rear) {
if(Arrays.equals(st[front], goal)) {
return front;
}
int z;
for(z = 0; z < 9; z++) {
if(st[front][z] == 0) {
break;
}
}
int x = z/3, y = z%3;
for(int d = 0; d < 4; d++) {
int newx = x + dx[d];
int newy = y + dy[d];
int newz = newx * 3 + newy;
if(newx >= 0 && newx < 3 && newy >= 0 && newy < 3) {
st[rear] = Arrays.copyOf(st[front], st[front].length);
st[rear][newz] = st[front][z];
st[rear][z] = st[front][newz];
dist[rear] = dist[front] + 1; if(try_to_insert(rear)) {
fa[rear] = front;
move[rear] = d;
rear++;
}
}
}
front++;
}
return 0;
}
public static String solve(String state) {
path = new StringBuffer();
for(int i = 0; i < state.length(); i++) {
st[1][i] = Integer.valueOf(state.charAt(i)) - '0';
}
int ans = bfs();
print_path(ans);
return path.toString();
}
}

下面是主函数

package com.EightNumber.view;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*; public class EightNumFrame extends Frame implements ActionListener,KeyListener
{
MenuBar menubar=new MenuBar();
Menu menu_file = new Menu("文件(F)");
MenuItem restart = new MenuItem("重新开始");
MenuItem nextPath = new MenuItem("提示");
MenuItem printPath = new MenuItem("还原");
MenuItem exit = new MenuItem("退出");
Button[] button;
Panel panel;
int row,col;
private static int position,cellNum;
final int dr[] = { 0,-1, 0, 1};
final int dc[] = {-1, 0, 1, 0};
public EightNumFrame(int row,int col) {
super.setMenuBar(menubar);
//Windows风格
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
this.row = row;
this.col = col;
cellNum = row*col; restart.addActionListener(this);
exit.addActionListener(this);
nextPath.addActionListener(this);
printPath.addActionListener(this);
menu_file.add(restart);
menu_file.add(nextPath);
menu_file.add(printPath);
menu_file.add(exit);
menubar.add(menu_file); panel = new Panel(new GridLayout(row,col)) ;
button = new Button[cellNum];
for(int i = 0; i < cellNum; i++) {
if(i == cellNum - 1) {
button[i] = new Button(" ");
}else {
button[i] = new Button(String.valueOf(i + 1));
}
button[i].setFont(new Font("Courier", 1, 20));
button[i].addActionListener(this);
button[i].addKeyListener(this);
panel.add(button[i]);
}
position = cellNum - 1;
this.add(BorderLayout.CENTER,panel);
this.setTitle("八数码");
this.setVisible(true);
this.setSize(300,300); Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width/2;
int screenHeight = screenSize.height/2;
int height = this.getHeight();
int width = this.getWidth();
this.setLocation(screenWidth-width/2, screenHeight-height/2);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
void start() {
int a[] = new int[9];
do {
int k = 0;
Random random=new Random();
Set<Integer> set=new HashSet<Integer>();
while(set.size() < cellNum-1) {
int n=random.nextInt(cellNum-1)+1;
if(!set.contains(n)) {
set.add(n);
a[k++] = n;
}
}
a[k] = 0;
}while(!EightNumPath.isok(a));
for(int i = 0; i < 9; i++)
button[i].setLabel(String.valueOf(a[i]));
button[cellNum-1].setLabel(" ");
position = cellNum - 1;
}
boolean win() {
for(int i = 0; i < cellNum - 1; i++) {
if(button[i].getLabel().equals(" ")) {
return false;
}else if(Integer.valueOf(button[i].getLabel()) != i+1) {
return false;
}
}
return true;
}
private boolean judge(Button a, Button b) {
for(int i = 0; i < 4; i++) {
if( (a.getX() == b.getX() + dr[i]*a.getWidth())
&& (a.getY() == b.getY() + dc[i]*a.getHeight())) {
return true;
}
}
return false;
} public void actionPerformed(ActionEvent e) {
StringBuffer state = new StringBuffer();
if(e.getSource() == restart) {
start();
return;
}else if(e.getSource() == exit) {
System.exit(0);
return;
}else if(e.getSource() == nextPath) {
for(int i = 0; i < cellNum; i++) {
if(button[i].getLabel().equals(" ")) {
state.append('0');
}else {
state.append(button[i].getLabel());
}
}
String path = EightNumPath.solve(state.toString());
JOptionPane.showMessageDialog(this,"建议走:"+path);
System.out.println(path);
return;
}else if(e.getSource() == printPath) {
for(int i = 0; i < cellNum; i++) {
if(button[i].getLabel().equals(" ")) {
state.append('0');
}else {
state.append(button[i].getLabel());
}
}
String path = EightNumPath.solve(state.toString());
for(int i = 0; i < path.length(); i++) {
switch(path.charAt(i)) {
case 'U':
go(KeyEvent.VK_UP);
break;
case 'D':
go(KeyEvent.VK_DOWN);
break;
case 'L':
go(KeyEvent.VK_LEFT);
break;
case 'R':
go(KeyEvent.VK_RIGHT);
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
for(int i = 0; i < cellNum; i++) {
if(e.getSource() == button[i]) {
if(!button[i].getLabel().equals(" ") && judge(button[i],button[position])) {
button[position].setLabel(button[i].getLabel());
button[i].setLabel(" ");
position = i;
}
}
}
if(win()) {
JOptionPane.showMessageDialog(this,"Congratulations");
}
}
void go(int dir) {
int x = position / col;
int y = position % col;
switch(dir) {
case KeyEvent.VK_UP:
if(x != 0) {
button[position].setLabel(button[position-col].getLabel());
button[position-col].setLabel(" ");
position -= col;
}
break;
case KeyEvent.VK_DOWN:
if(x != row-1) {
button[position].setLabel(button[position+col].getLabel());
button[position+col].setLabel(" ");
position += col;
}
break;
case KeyEvent.VK_LEFT:
if(y != 0) {
button[position].setLabel(button[position-1].getLabel());
button[position-1].setLabel(" ");
position -= 1;
}
break;
case KeyEvent.VK_RIGHT:
if(y != col-1) {
button[position].setLabel(button[position+1].getLabel());
button[position+1].setLabel(" ");
position += 1;
}
break;
}
}
public void keyPressed(KeyEvent e) {
go(e.getKeyCode());
if(win()) {
JOptionPane.showMessageDialog(this,"Congratulations");
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
new EightNumFrame(3, 3);
}
}

八数码 Java实现的更多相关文章

  1. A*算法解决八数码问题 Java语言实现

    0X00 定义 首先要明确一下什么是A*算法和八数码问题? A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法也是一种启发性的算法,也是解决许多搜索问题的有效算法.算法中的距离估 ...

  2. Java实现 蓝桥杯 算法提高 八数码(BFS)

    试题 算法提高 八数码 问题描述 RXY八数码 输入格式 输入两个33表格 第一个为目标表格 第二个为检索表格 输出格式 输出步数 样例输入 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 ...

  3. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  4. HDU 3567 Eight II(八数码 II)

    HDU 3567 Eight II(八数码 II) /65536 K (Java/Others)   Problem Description - 题目描述 Eight-puzzle, which is ...

  5. HDU 1043 Eight(八数码)

    HDU 1043 Eight(八数码) 00 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)   Problem Descr ...

  6. Eight(经典题,八数码)

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. Poj 1077 eight(BFS+全序列Hash解八数码问题)

    一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1  2  X            3 4  6            7  5  8 ...

  8. 八数码问题:C++广度搜索实现

    毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...

  9. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

随机推荐

  1. dhtmlxgrid v3.0学习笔记

    dhtmlxgrid v3.0学习笔记 分类: dhtmlx JavaScript2012-01-31 15:41 1744人阅读 评论(0) 收藏 举报 stylesheetdatecalendar ...

  2. Spark- 常见问题

    记录spark使用中常见问题 SparkSQL 日期解析时用到SimpleDateFormat, SimpleDateFormat是线程不安全的.可以使用 FastDateFormat 如: impo ...

  3. SpringMVC 文件上传及下载

    首先需要导入jar包 创建一个jsp页面 package cn.happy.Controller; import java.io.File; import javax.servlet.http.Htt ...

  4. python3字符串属性(二)

    1.S.isdecimal() -> bool    Return True if there are only decimal characters in S, False otherwise ...

  5. 分享知识-快乐自己:mybatis 主键回调

    以下两种方式实现 主键回掉方式. <!--添加用户信息:主键回调--> <insert id="insertUser" useGeneratedKeys=&quo ...

  6. 如何在node.js中使用neo4j

    本章中你将会学到如何在node.js中使用neo4j图形数据库. 当你想存储或者查询和数据紧密关联的数据的时候,图形数据库很有用. neo4j是一个可有效存储,处理和查询你数据模型中紧密相连的元素的数 ...

  7. 4 Python 日期和时间

    Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 时间间隔是以秒为单位的浮点小数. ...

  8. BEC listen and translation exercise 39

    What about jigsaw puzzle design for visually handicapped?给视觉障碍人士设计拼图怎么样? Length is 50cm, and then th ...

  9. MFC实现普通DLL

    库有两种:动态链接库和静态链接库. 一,使用动态链接库: 通过项目——属性——配置属性——常规——项目默认值——配置类型下,选择动态库(.dll)选项 这样会生成.lib和.dll两种文件. 只是该. ...

  10. poj-1379 Run Away(模拟退火算法)

    题目链接: Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 7982   Accepted: 2391 De ...