poj-1077 (bfs+cantor expansion)

Link to the original question http://poj.org/problem?id=1077
The general idea of ​​the question is to turn the Jiugongge you input into the target Jiugongge (probably played this kind of game when I was young, and restore the Jiugongge), and then output the direction of each movement . If you don’t know Cantor’s development, you can Baidu it, it’s very useful for judging the weight of the whole arrangement. When submitting, c++ has been timed out, and it still doesn't work after changing it. It's ac after changing it to g++, which is depressed.
The code is as follows (with solution)

#include<iostream>
#include<queue>
#include<cstring>
#include<stdio.h>
using namespace std;
const int Len = 362880;//一共有9!种全排列
struct node{
    
    
    int state[9];
    int count;//记录步数
    char d[100];//记录每一步的方向
};
int vis[Len] = {
    
    0};//0表示第Len种情况还没出现过
int start[9];
int goal[9] = {
    
    1,2,3,4,5,6,7,8,0};
int dir[4][2] = {
    
    //4个方向
    {
    
    0,-1},//up
    {
    
    1,0},//right
    {
    
    0,1},//down
    {
    
    -1,0}//left
    
   
};

long int factory[] = {
    
    1,1,2,6,24,120,720,5040,40320,362880};//康托展开常用阶乘

bool Cantor(int str[], int n){
    
    //康托展开,判重
    long result = 0;
    for(int i = 0; i<n; i++){
    
    
        int count = 0;
        for(int j=i+1; j<n; j++){
    
    
            if(str[i]>str[j])
                count++;
        }
        result += count*factory[n-i-1];
    }
    if(!vis[result]){
    
    
        vis[result] = 1;//标记为已经出现过
        return 1;
    }
    else
        return 0;
    
}

int bfs(){
    
    
    node head;
    queue<node> q;
    memcpy(head.state,start,sizeof(head.state));
    head.count = 0;
    Cantor(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)//记录0的位置
                break;
        int x,y;
        x = z%3;
        y = z/3;//转化为二维坐标
        for(int i = 0; i<4; i++){
    
    //4个方向
            int newx,newy;
            newx = x + dir[i][0];
            newy = y + dir[i][1];
            int nz = newx + 3*newy;//转化回一维坐标

            if(newx>=0 && newx<3 && newy>=0 && newy <3){
    
    //没有越界
                node newnode;
                memcpy(&newnode,&head,sizeof(node));
                swap(newnode.state[z],newnode.state[nz]);//换位
                
                if(i == 0){
    
    newnode.d[newnode.count] = 'u';newnode.count++; }//记录每一步
                if(i == 1){
    
    newnode.d[newnode.count] = 'r';newnode.count++; }
                if(i == 2){
    
    newnode.d[newnode.count] = 'd';newnode.count++; }
                if(i == 3){
    
    newnode.d[newnode.count] = 'l';newnode.count++; }

                if(memcmp(newnode.state,goal,sizeof(goal)) == 0){
    
    //找到了
                    for(int j = 0; j<newnode.count; j++){
    
    
                        printf("%c",newnode.d[j]);
                    }
                    return 1;
                }
                if(Cantor(newnode.state,9)){
    
    //不重复
                    q.push(newnode);
                }
                
            }

        }
    }
    return -1;//没有找到
}
int main()
{
    
       
    char s[100];
    int k = 0;
    gets(s);
    char *p;
    for( p = s; *p != '\0'; p++){
    
    
        if( *p != ' '){
    
    
            if(*p == 'x')
                start[k++] = 0;//把x转化为0
            else
                start[k++] = *p -'0';
        }
    }


    int num = bfs();
    if(num == -1)
        cout<<"unsolvable"<<endl;
    cin.get();
    cin.get();

    return 0;
}

Just started to learn bfs, record it, if there is any problem, I hope you can point it out.

Guess you like

Origin blog.csdn.net/weixin_45732455/article/details/104944661