zoukankan      html  css  js  c++  java
  • [题解]八数码问题

    原题链

    提交情况

    解题思路:

    广搜。首先读入,然后特判是不是不需要变换就直接是最后结果(有一个点)。接着入队当前状态,所需步数为(0)。然后就是普通广搜的过程。分为(4)个方向。每次进行扩展时,都现将表示当前状态的9位数变为一个3×3的矩阵,然后扩展,并判断是否合法。如果合法,则又将(3×3)的矩阵变为一个9位数作为函数的返回值。当一遍广搜进行完闭后,就判断是否为目标状态。如果不是,就进行判重。

    源代码:

    #include <bits/stdc++.h>
    using namespace std;
    int end_state = 123804765;
    map < int,bool > vis;
    int a[10][10],x,y;
    struct node {
    	int state,tm;
    };
    inline void build(int key){
    	if(key % 10 == 0)x = 2,y = 2;a[2][2] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 2,y = 1;a[2][1] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 2,y = 0;a[2][0] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 1,y = 2;a[1][2] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 1,y = 1;a[1][1] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 1,y = 0;a[1][0] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 0,y = 2;a[0][2] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 0,y = 1;a[0][1] = key % 10;key /= 10;
    	if(key % 10 == 0)x = 0,y = 0;a[0][0] = key % 10;key /= 10;
    }
    inline int work(int direction,int state) {
    	int key = state;
    	build(key);
    	switch(direction){
    		case(1):if(x == 0) return key;swap(a[x][y],a[x - 1][y]);break;//上 
    		case(2):if(x == 2) return key;swap(a[x][y],a[x + 1][y]);break;//下
    		case(3):if(y == 0) return key;swap(a[x][y],a[x][y - 1]);break;//左
    		case(4):if(y == 2) return key;swap(a[x][y],a[x][y + 1]);break;//右 
    	} 
    	key = 0;
    	for(int i = 0;i <= 2;i++){
    		for(int j = 0;j <= 2;j++){
    			key = key * 10 + a[i][j];
    		}	
    	}
    	return key;
    }
    queue < node > q;
    int main() {
    	int now_state;
    	cin>>now_state;
    	node t;
    	t.state = now_state;t.tm = 0;
    	q.push(t);
    	int tmp;
    	if(now_state == end_state)cout<<0,exit(0);
    	while(!q.empty()){
    		node now,use = q.front();q.pop();
    		now_state = work(1,use.state);
    		if(now_state == end_state){cout<<use.tm + 1;exit(0);}
    		else if(!vis[now_state]){vis[now_state] = true;q.push((node){now_state,use.tm + 1});}
    		now_state = work(2,use.state);
    		if(now_state == end_state){cout<<use.tm + 1;exit(0);}
    		else if(!vis[now_state]){vis[now_state] = true;q.push((node){now_state,use.tm + 1});}
    		now_state = work(3,use.state);
    		if(now_state == end_state){cout<<use.tm + 1;exit(0);}
    		else if(!vis[now_state]){vis[now_state] = true;q.push((node){now_state,use.tm + 1});}
    		now_state = work(4,use.state);
    		if(now_state == end_state){cout<<use.tm + 1;exit(0);}
    		else if(!vis[now_state]){vis[now_state] = true;q.push((node){now_state,use.tm + 1});}
    	}
    	return 0;
    }
    
  • 相关阅读:
    指针的相关概念
    Linux库函数
    计算机组成
    常用校验码及示例
    判断文件是否被占用的三种方法
    服务主机superFetch占用磁盘过多
    renameTo()判断文件是否被占用(判断大文件是否完成拷贝这个动作)
    xshell下mysql数据库只导出表结构不导出数据
    Java_判断文件是否写入完成
    Java_监听文件夹或者文件是否有变动
  • 原文地址:https://www.cnblogs.com/czy--blog/p/11741849.html
Copyright © 2011-2022 走看看