微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

hdu 1043/poj 1077八数码问题 BFS+康托展开求解

hdu
poj

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct node{
    int state[9];
    string change;  //记录变化轨迹
};
const int LEN=362880;
int factorial[9]={1,1,2,6,24,120,720,5040,40320};
int visited[LEN]={0};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char movement[4]={'r','l','d','u'};
int ans[9]={1,2,3,4,5,6,7,8,0};
int Canor(int str[],int n){
    int result=0,count=0;
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            if(str[j]<str[i]){
                count++;
            }
        }
        result+=count*factorial[n-i-1];
        count=0;
    }
    if(visited[result]){
        return 1; //重复
    }
    else{
        visited[result]=1;
        return 0;
    }
}
bool judge(int x[],int y[]){
    for(int i=0;i<9;i++){
        if(x[i]!=y[i]){
            return false;
        }
    }
    return true;
}
void BFS(int input[]){
    if(judge(input,ans)){
        return;
    }
    node head;
    memcpy(head.state,input,sizeof(head.state));
    queue<node>q;
    Canor(head.state,9);
    q.push(head);
    while(!q.empty()){
        head=q.front();
        q.pop();
        int z;
        for(z=0;z<9;z++){
            if(head.state[z]==0){
                break;
            }
        }
        int x=z%3;
        int y=z/3;
        for(int i=0;i<4;i++){
            int newx=x+dir[i][0];
            int newy=y+dir[i][1];
            char c=movement[i];
            int nz=newx+newy*3; //新一维坐标
            if(newx>=0&&newx<3&&newy>=0&newy<3){
                node newnode;
                newnode=head;
                swap(newnode.state[z],newnode.state[nz]);
                newnode.change+=c;
                if(!Canor(newnode.state,9)){ //判定没有重复
                    if(judge(newnode.state,ans)){
                        //得到结果,输出
                        for(int i=0;i<newnode.change.size();i++){
                           cout<<newnode.change[i];
                        }
                        cout<<endl;
                        return;
                    }
                    q.push(newnode);
                }
            }
        }
    }
    cout<<"unsolvable"<<endl;
    return;
}
int main(){
    char str[18];
    int input[9]={0},x=0,y=0;
    int cnt=0;
    while(gets(str)){
        for(int i=0;i<strlen(str);i++){
            if(str[i]>='0'&&str[i]<='9'){
                input[cnt++]=str[i]-'0';
            }
            else if(str[i]=='x'){
                input[cnt++]=0;
            }
        }
        BFS(input);
        //reset
        cnt=0;
        for(int i=0;i<LEN;i++){
            visited[i]=0;
        }
    }
    return 0;
}

牛客网OJ能过,HDU和POJ平台显示超时

原文地址:https://www.jb51.cc/wenti/3283506.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐