uva 10085 The most distant state

原题:
The 8-puzzle is a square tray in which eight square tiles are placed. The remaining ninth square is uncovered. Each tile has a number on it. A tile that is adjacent to the blank space can be slid into that space. A game consists of a starting state and a specified goal state. The starting state can be transformed into the goal state by sliding (moving) the tiles around. The 8-puzzle problem asks you to do the transformation in minimum number of moves.
这里写图片描述
However, our current problem is a bit different. In this problem, given an initial state of the puzzle your are asked to discover a goal state which is the most distant (in terms of number of moves) of all the states reachable from the given state.
Input
The first line of the input file contains an integer representing the number of test cases to follow. A blank line follows this line. Each test case consists of 3 lines of 3 integers each representing the initial state of the puzzle. The blank space is represented by a ‘0’ (zero). A blank line follows each test case.
Output
For each test case first output the puzzle number. The next 3 lines will contain 3 integers each representing one of the most distant states reachable from the given state. The next line will contain the shortest sequence of moves that will transform the given state to that state. The move is actually the movement of the blank space represented by four directions: ‘U’ (Up), ‘L’ (Left), ‘D’ (Down) and‘R’ (Right).
After each test case output an empty line.
Sample Input
1
2 6 4
1 3 7
0 5 8
Sample Output
Puzzle #1
8 1 5
7 3 6
4 0 2
UURDDRULLURRDLLDRRULULDDRUULDDR

中文:
给你一个八数码的起始状态,然后问你距离这个这个八数码最远的一个状态是什么样?

#include <bits/stdc++.h>
using namespace std;
struct node
{
    string st;
    vector<char> dir;
};
unordered_map<string,node> ums;
int t;
node Down(node n,int pos)
{
    if(pos>=6)
    {
        n.st="#";
        return n;
    }
    swap(n.st[pos],n.st[pos+3]);
    n.dir.push_back('D');
    return n;
}
node Up(node n,int pos)
{
    if(pos<3)//0在第一行
    {
        n.st="#";
        return n;
    }
    swap(n.st[pos],n.st[pos-3]);
    n.dir.push_back('U');
    return n;
}
node Left(node n,int pos)//不能在最右侧
{
    if(pos%3==2)
    {
        n.st="#";
        return n;
    }
    swap(n.st[pos],n.st[pos+1]);
    n.dir.push_back('R');
    return n;
}
node Right(node n,int pos)
{
    if(pos%3==0)
    {
        n.st="#";
        return n;
    }
    swap(n.st[pos],n.st[pos-1]);
    n.dir.push_back('L');
    return n;
}
node bfs(node start,string state)
{
    queue<node> Q;
    Q.push(start);
    ums[state]=start;
    node ans;
    int _max=0;
    while(!Q.empty())
    {
        node head=Q.front();
//        cout<<head.st<<endl;
        if(head.dir.size()>_max)
//        if(head.dir.size()==31)//如果步数等于31就break返回答案
        {
            ans=head;
//            break;
            _max=head.dir.size();
        }
        Q.pop();
        int zero=head.st.find('0');
        node u=Up(head,zero);
        node d=Down(head,zero);
        node l=Left(head,zero);
        node r=Right(head,zero);
        if(u.st!="#")
        {
            if(ums.find(u.st)==ums.end())
            {
                ums.insert(make_pair(u.st,u));
                Q.push(u);
            }
        }
        if(d.st!="#")
        {
            if(ums.find(d.st)==ums.end())
            {
                ums.insert(make_pair(d.st,d));
                Q.push(d);
            }
        }
        if(l.st!="#")
        {
            if(ums.find(l.st)==ums.end())
            {
                ums.insert(make_pair(l.st,l));
                Q.push(l);
            }
        }
        if(r.st!="#")
        {
            if(ums.find(r.st)==ums.end())
            {
                ums.insert(make_pair(r.st,r));
                Q.push(r);
            }
        }
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    int k=1;
    while(t--)
    {
        string st;
        node start;
        ums.clear();
        for(int i=1;i<=9;i++)
        {
            string s;
            cin>>s;
            st+=s;
        }
        start.st=st;
        node ans=bfs(start,st);
        cout<<"Puzzle #"<<k++<<endl;
        for(int i=0;i<ans.st.size();i++)
        {
            cout<<ans.st[i];
            if((i+1)%3==0)
                cout<<endl;
            else
                cout<<" ";
        }
//        cout<<ans.dir.size()<<endl;
        for(auto c:ans.dir)
            cout<<c;
        cout<<endl;
        cout<<endl;
    }
    return 0;
}

解答:

要找最远的状态,使用广搜,搜索到队列最后一个状态,也就是最远的状态了。可以使用康拓展开或者是哈希函数来实现。

本以为写完代码以后会超时,结果一下题目上的时间要求是13s,晕~

不过,通过自己写了两组数据发现了一个此题的规律!那就是最远状态的路径长度一定是等于31步,但是没有证明,我自己猜的,使用这个结论以后还ac了,又因为八数码问题可以使用启发式搜索来解答,所以我感觉此题绝对可以有很大的优化空间,看了榜单,有很多的0s过的,但是自己还没想出来-_-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值