zoukankan      html  css  js  c++  java
  • 43-八数码

    题题目内容:
    在3*3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局和目标布局,为了使题目简单,设目标状态为:
    1 2 3
    8 0 4
    7 6 5
    找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变.
    输入描述
    输入初试状态,3*3的九个数字,空格用0表示.

    输出描述
    只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次
    (若无法到达目标状态则输出-1).

    输入样例
    2 8 3
    1 0 4
    7 6 5

    输出样例
    4
    #include <iostream>
    #include <set>
    #include <cstring>
    using namespace std;
    typedef int State[9];   		  //定义状态类型 
    const int maxstate = 10000000;	 	
    int goal[9]{
    	1, 2, 3,
    	8, 0, 4,
    	7, 6, 5
    };
    State st[maxstate];				  //状态数组,保存所有状态	
    int dist[maxstate];				  //距离数组	
    								  //如果需要打印方案,可以在这里加一个"父亲编号"数组int fa[maxstatue] 
    const int dx[] = {-1, 1, 0, 0};
    const int dy[] = {0, 0, -1, 1};
    
    set<int> vis;
    void init_lookup_table(){
    	vis.clear();
    }
    int try_to_insert(int s){
    	int v = 0;
    	for(int i = 0; i < 9; i++)
    		v = v * 10 + st[s][i];
    	if(vis.count(v))
    		return 0;
    	vis.insert(v); 
    	return 1;
    } 
    
    int bfs(){						 //bfs,返回目标状态在st数组下标 
    	init_lookup_table();         //初始化查找表 
    	int front = 1, rear =  2;	 //不使用下标0,因为0被看作“不存在” 
    	while(front < rear){ 
    		State& s = st[front];   //用引用简化代码			
    		if(memcmp(goal, s, sizeof(s)) == 0)
    			return front;            //找到目标状态,成功返回
    		int z;
    		for(z = 0; z < 9; z++)		 //找到0的位置 
    			if(!s[z]) 
    				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){   //判断是否移动合法 
    				State& t = st[rear];
    				memcpy(&t, &s, sizeof(s));   //扩展新结点
    				t[newz] = s[z];
    				t[z] = s[newz];
    				dist[rear] = dist[front] + 1; //更新新结点的距离值 
    				if(try_to_insert(rear))
    					rear++;
    			} 
    		}		 
    		front++; //扩展完毕再修改对首指针 
    //		cout << front << " ";
    	}
    	return 0;    //失败	 
    }
    
    int main(){
    	for(int i = 0; i < 9; i++)
    		cin >> st[1][i];
    	for(int i = 0; i < 9; i++)
    		cin >> goal[i];
    	int ans = bfs();
    	if(ans > 0)
    		cout << dist[ans] ;
    	else
    		cout << -1;
    		
    	return 0;
    } 
    
  • 相关阅读:
    万维网
    MySQL客户端输出窗口显示中文乱码问题解决办法
    mysql数据库delete数据时不支持表别名
    Java 实现在固定区间内随机生成整数
    【面试】MySQL 中NULL和空值的区别?
    一个因MySQL大小写敏感导致的问题
    windows查看服务的状态
    不就是Select Count语句吗,竟然能被面试官虐的体无完肤!
    Java 代码的精优化
    java服务宕机原因查询
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/7748045.html
Copyright © 2011-2022 走看看