首页 > 其他 > 详细

A*算法-历届试题 九宫重排

时间:2014-03-15 21:35:34      阅读:741      评论:0      收藏:0      [点我收藏+]

 历届试题 九宫重排  

时间限制:1.0s   内存限制:256.0MB
      
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
bubuko.com,布布扣bubuko.com,布布扣
  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22
 
 
fuck啊,只对了80%;骚年努力!没有过不去的坎,没有A不掉的题!
bubuko.com,布布扣
#define _CRT_SECURE_NO_DEPRECATE
//A*八数码问题
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#define MAX 1
using namespace std;

int dx[4] = { 0, 0, 1, -1 }, dy[4] = { 1, -1, 0, 0 };

class NODE{
public:
    NODE(){ memset(m, 0, sizeof(m)); flag = f = g = h = 0; par = NULL; }
    ~NODE(){}
    char m[3][3];
    //矩阵对应的十进制数
    int flag;
    //估价函数
    int f, g, h;
    //空格坐标
    int tx, ty;
    //父节点
    NODE *par;
    //转换函数
    void m2f(){
        flag=0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                if(m[i][j]!=.)flag = 10*flag+(m[i][j]-0);
                else { flag *= 10; tx = i; ty = j; }
            }
        }
    }
    void init(char *c){
        int i=0;
        for(int j=0;j<3;j++)for(int k=0;k<3;k++)m[j][k]=c[i++];
        m2f();
    }
    //计算f
    void calf(NODE T){
        //h是与目标位置不同数的个数
        for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)if (m[i][j] != T.m[i][j])h++;
        
        //h:离对应点的距离
        for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++){
            for (int k = 0; k < 3; k++)for (int l = 0; l < 3; l++)
                if (m[i][j] == T.m[k][l]){ h += abs(k + l - i - j); }
        }
    
        if (par != NULL){ g = par->g + 1; f = g + h; }
        else f = h;
    }
    void print(){
        printf("%d\n",flag);
    }
};

NODE orig,targ;

//Open表中按f从小到大排序
struct great{
    bool operator()(NODE N1,NODE N2){
        return N1.f > N2.f;
    }
};

//Open表和Close表
priority_queue<NODE,vector<NODE>, great> OList;
vector<NODE> CList;
vector<NODE>::iterator itor;
//A*
void AStar(){
    int step = 0;
    char temp;
    //找到结果
    bool find = false;
    OList.push(orig);
    //如果Open表空,无解
    while (!OList.empty()){
        //把Open表第一个取出,记为n,加入Close表
        NODE n = OList.top(); OList.pop();
        CList.push_back(n);
        //n是否为目标节点,是则成功退出
        if (n.h == 0){ find = true; step = n.g; break; }
        //n是否可扩展
        for (int i = 0; i < 4; i++){
            int x = n.tx + dx[i], y = n.ty + dy[i];
            if (x>-1 && x<3 && y>-1 && y < 3){
                NODE t;
                for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)t.m[i][j] = n.m[i][j];
                t.tx = x; t.ty = y;
                temp = t.m[n.tx][n.ty];
                t.m[n.tx][n.ty] = t.m[x][y];
                t.m[x][y] = temp;
                t.m2f();
                t.par = &n;
                t.calf(targ);
                if (n.par == NULL || t.flag != n.par->flag){
                    bool inCL = false;
                    for (itor = CList.begin(); itor != CList.end(); itor++){
                        if (t.flag == itor->flag){ inCL = true; break; }
                    }
                    if (!inCL)OList.push(t);
                }
            }
        }
    }
    if (find){
        printf("%d\n", step);
    }
    else{
        printf("-1\n");
    }
}

int main()
{
    char c[10];
    //while(1){
        gets(c);
        orig.init(c);
        gets(c);
        targ.init(c);
        orig.calf(targ);

        AStar();
    //}
    return 0;
}
bubuko.com,布布扣

 

A*算法-历届试题 九宫重排,布布扣,bubuko.com

A*算法-历届试题 九宫重排

原文:http://www.cnblogs.com/littlehoom/p/3602217.html

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