hdu 1043 Eight(8数码,第三重)

小记:8数码境界还只有第三重,还要继续加油。

 

做法:第一重,stl + bfs 暴力, 9!数量级,在重复询问的状态下,超时是必然的

         第二重,hash + bfs  ,自己做hash函数,自己想个hash函数出来,hdu的5秒 这样做 应该能过,poj 1s 就算了

         第三重,hash + 反向bfs + 打表, hash 我是用map做的, 同时用map记录表,因为是反向的,所以在询问某一个,要输出答案时,反向输出。

         第四重,在想...

 

第一重代码:

#include <iostream>
#include <map>
#include <string>
#include <queue>
using namespace std;

const int MAX_ = 10;

int f[MAX_][MAX_];

int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
char ss[4] = {'u','d','l','r'};

struct point {
    int init[MAX_][MAX_];
    int x,y;
    string str;
} s;
map<int,bool>mp;

void bfs() {
    queue<point>q;
    s.str="";
    q.push(s);
    mp.clear();

    while(!q.empty()) {
        point cur, next;
        cur = q.front();
        q.pop();
        bool flag = 1;
        for(int i = 1; i < 4; ++i) {
            for(int j = 1; j < 4; ++j) {
                if(cur.init[i][j] != f[i][j]) {
                    flag = 0;
                    break;
                }
            }
            if(!flag)break;
        }
        if(flag) {
            //show(cur);
            cout<<cur.str<<endl;
            return;
        }
        for(int i = 0; i < 4; ++i) {
            next.x = cur.x + dir[i][0];
            next.y = cur.y + dir[i][1];
            if((next.x >= 1 && next.x <= 3) &&(next.y >= 1 && next.y <= 3)) {
                for(int k = 1; k < 4; ++k) {
                    for(int j = 1; j < 4; ++j) {
                        next.init[k][j] = cur.init[k][j];
                    }
                }
                swap(next.init[next.x][next.y],next.init[cur.x][cur.y]);
                next.str = cur.str;
                next.str.push_back(ss[i]);
                int cnt = 0;
                for(int k =1; k < 4; ++k) {
                    for(int j = 1; j < 4; ++j) {
                        cnt = cnt*10 + next.init[k][j];
                    }
                }
                if(mp.find(cnt) == mp.end()) {
                    mp[cnt] = 1;
                    q.push(next);
                }

            }
        }
    }
    cout<<"unsolvable"<<endl;

}


int main() {
    char c;
    int sx,sy;
    while(cin>>c) {
        c == 'x'?s.init[1][1] = 0:s.init[1][1] = c- '0';
        for(int i = 2; i < 4; ++i) {
            cin>> c;
            c == 'x'?s.init[1][i] = 0:s.init[1][i] = c - '0';
        }
        for(int i = 2; i < 4; ++i) {
            for(int j = 1; j < 4;  ++ j) {
                cin>>c;
                c == 'x'?s.init[i][j] = 0:s.init[i][j] = c - '0';
            }
        }
        for(int i = 1; i < 4; ++i) {
            for(int j = 1; j < 4;  ++ j) {
                if(s.init[i][j] == 0) {
                    s.x = i, s.y = j;
                }
            }
        }
        int cnt = 1;
        for(int i = 1; i < 4; ++i) {
            for(int j = 1; j < 4; ++j) {
                f[i][j] = cnt++;
                cnt %= 9;
            }
        }

        bfs();


    }
    return 0;
}


 

 

第二重,懒得想了,

直接第三重:

#include <iostream>
#include <map>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;

const int MAX_ = 10;

int f[MAX_][MAX_];

int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
char ss[4] = {'d','u','r','l'};

struct point {
    int init[MAX_][MAX_];
    int x,y;
    string str;
} s;
map<int,string>mp;

void bfs() {
    queue<point>q;
    s.str="";
    q.push(s);
    mp.clear();

    while(!q.empty()) {
        point cur, next;
        cur = q.front();
        q.pop();

        for(int i = 0; i < 4; ++i) {
            next.x = cur.x + dir[i][0];
            next.y = cur.y + dir[i][1];
            if((next.x >= 1 && next.x <= 3) &&(next.y >= 1 && next.y <= 3)) {
                for(int k = 1; k < 4; ++k) {
                    for(int j = 1; j < 4; ++j) {
                        next.init[k][j] = cur.init[k][j];
                    }
                }
                swap(next.init[next.x][next.y],next.init[cur.x][cur.y]);
                next.str = cur.str;
                next.str.push_back(ss[i]);
                int cnt = 0;
                for(int k =1; k < 4; ++k) {
                    for(int j = 1; j < 4; ++j) {
                        cnt = cnt*10 + next.init[k][j];
                    }
                }
                if(mp.find(cnt) == mp.end()) {
                    mp[cnt] = next.str;
                    q.push(next);
                }

            }
        }
    }
}


int main() {
    char c;
    int sx,sy;
    int cnt = 1;
    for(int i = 1; i < 4; ++i) {
        for(int j = 1; j < 4; ++j) {
            s.init[i][j] = cnt++;
            cnt %= 9;
        }
    }
    s.x = 3, s.y = 3;
    bfs();
    while(cin>>c) {
        c == 'x'?f[1][1] = 0:f[1][1] = c- '0';
        for(int i = 2; i < 4; ++i) {
            cin>> c;
            c == 'x'?f[1][i] = 0:f[1][i] = c - '0';
        }
        for(int i = 2; i < 4; ++i) {
            for(int j = 1; j < 4;  ++ j) {
                cin>>c;
                c == 'x'?f[i][j] = 0:f[i][j] = c - '0';
            }
        }

        int cnt = 0;
        for(int k =1; k < 4; ++k) {
            for(int j = 1; j < 4; ++j) {
                cnt = cnt*10 + f[k][j];
            }
        }
        if(mp.find(cnt) == mp.end()) {
            cout<<"unsolvable"<<endl;
        }
        else {
            reverse(mp[cnt].begin(),mp[cnt].end());
            cout<<mp[cnt]<<endl;
        }

    }
    return 0;
}


 

你可能感兴趣的:(hdu 1043 Eight(8数码,第三重))