1015 八数码 bfs


题目描述

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as: 
这个第十五道题,已经存在了一百年以上了,即使你不知道它的名字,你一定也见过它。它由十五个浮动瓷砖组成,每个瓷砖有一个1到15的数字,并且这些瓷砖被塞进一个4*4的方块里,方块少了一个瓷砖。让我们叫这个少的瓷砖为‘x’,这个问题是让这些瓷砖移动使它有序。比如:

 1  2  3  4 

 5  6  7  8 

 9 10 11 12 

13 14 15  x 
where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle: 
仅有一种合法操作使'x' 与它相连的唯一的瓷砖交换。例如,下面的操作解决了一个略显复杂的谜题。
 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 

 5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8 

 9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12 

13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x 

           r->           d->           r-> 

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively. 
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course). 
In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
arrangement. 
前一行中的字母表示在每一步中'x' 瓷砖的哪个邻居与'x' 交换;合法的值是'r','l','u' and 'd',对应右左上和下。
并且并非所有谜题都能解决;1870年,一个叫做山姆罗伊德因发行了一个无法解决的谜题版本而闻名,并打击了很多人。事实上,要让一个普通谜题变成无法解决的谜题,只需要交换两个贴图。
(不包括x贴图)。
 

输入描述:

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle
1 2 3

x 4 6

7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8

输出描述:

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.
示例1

输入

复制
 2  3  4  1  5  x  7  6  8 

输出

复制
ullddrurdllurdruldr

分析

用map存每个状态对应的改变
然后bfs每一个状态
可以交换字符串中的两个值来改变当前的字符串
通过除以长度,和模长度得到当前位置在9*9方格中的相对坐标


//-------------------------代码----------------------------

#define int LL
const int N = 1e5+10;
int n,m;
string s;
int a[100];
unordered_map<string,string> mp;


void bfs() {
    queue<string>q;
    q.push(s); //初始状态
    mp[s] = "";
    string ed = "12345678x";  //结束状态
    while(q.size()) {
        auto t = q.front();q.pop();
        if(t == ed) {cout<<mp[t];rt;}
        
        
        int pos = t.find('x');           //找到当前字符串中x的位置
        int x = pos / 3, y = pos % 3;    //一维位置转二维坐标
        string dt = mp[t];
        
        
        for(int i = 0;i<4;i++) {
            int xx = x + dx[i],yy = y + dy[i];
            if(xx < 0 || yy < 0 || xx >= 3 || yy >= 3) continue;
            string s1 = t;
            swap(s1[xx * 3 + yy],s1[pos]);
            if(mp.count(s1)) continue;    //不小心把count中间的值写成了t
            mp[s1] = dt + dc[i];
            q.push(s1);
        }
    }
    cout<<"unsolvable";
}
 
void solve()
{
    s = "";
    for(int i = 1;i<=9;i++) {//*忘了输入要一个个输入了
        char c;
        cin>>c;
        s += c;
    }
    bfs();
    
}

signed main(){

    TLE;
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

忘了字符串是一个字符一个字符输入的直接cin>>s 了。。
不小心把map 的count 里的变量写成了t 这个变换前的变量。。
posted @ 2022-06-30 22:02  er007  阅读(16)  评论(0编辑  收藏  举报