uva-704-暴力枚举-双向bfs

题意:俩个转盘,24个数字,每个转盘都可以顺时针,逆时针旋转.终点固定.

问:给定一个起点,能不能在16步内转到终点

解法:双向bfs,终点走8步,起点走8步,判断从起点生成的状态是否在终点里面,如果在即是有解

注意题目要输出转动的方向,并且方向字符串要最小,所以,在某一步有解事,要把当前层数走完,取最小值

#include <iostream>
#include<map>
#include<memory.h>
#include<stdio.h>
#include<string>
#include<queue>

using namespace std;



const int MAXN = 24;


string zhuan(string str, int way)
{
    string reStr(str);
    if (way == 1)
    {
        //左边顺时针旋转
        char sb1 = str[10];
        char sb2 = str[11];
        for (int i = 11;i >= 2;i--)
            reStr[i] = reStr[i - 2];
        reStr[1] = sb2;
        reStr[0] = sb1;
        reStr[23] = reStr[11];
        reStr[22] = reStr[10];
        reStr[21] = reStr[9];
    }
    else if (way == 3)
    {
        //左边逆时针旋转
        char sb1 = reStr[0];
        char sb2 = reStr[1];
        for (int i = 0;i < 10;i++)
            reStr[i] = reStr[i + 2];
        reStr[11] = sb2;
        reStr[10] = sb1;
        reStr[23] = reStr[11];
        reStr[22] = reStr[10];
        reStr[21] = reStr[9];
    }
    else if (way == 2)
    {
        //右边顺时针旋转
        char sb1 = reStr[12];
        char sb2 = reStr[13];
        for (int i = 12;i < 22;i++)
            reStr[i] = reStr[i + 2];
        reStr[23] = sb2;
        reStr[22] = sb1;
        reStr[11] = reStr[23];
        reStr[10] = reStr[22];
        reStr[9] = reStr[21];
    }
    else
    {
        //右边逆时针旋转
        char sb1 = reStr[22];
        char sb2 = reStr[23];
        for (int i = 23;i >= 12;i--)
            reStr[i] = reStr[i - 2];
        reStr[13] = sb2;
        reStr[12] = sb1;
        reStr[11] = reStr[23];
        reStr[10] = reStr[22];
        reStr[9] = reStr[21];
    }
    return reStr;
}


class Node 
{
public:
    string str;
    string step;
    int stepNum;
    bool operator < (const Node& node) const
    {
        return stepNum > node.stepNum;
    }
};

const static string endState = "034305650121078709a90121";
map<string, string> sMap;
map<string, string>eMap;
priority_queue<Node> q;


int ok = 0;
string curStep = "";

string path(string es) 
{
    string str = "";
    for (int i = es.size() - 1; i >= 0;i--)
    {
        if (es.at(i) == '1') str+= "3";
        else if (es.at(i) == '3') str += "1";
        else if (es.at(i) == '2')str += "4";
        else if (es.at(i) == '4') str += "2";
    }
    return str;
}

//8
void bfsEnd() 
{
    while (!q.empty())
        q.pop();
    Node n;
    n.step = "";
    n.stepNum = 0;
    n.str = endState;
    q.push(n);
    eMap[endState] = "";
    while (!q.empty()) 
    {
        n = q.top();
        q.pop();
        if (n.stepNum == 8)
            break;
        for (int i=1;i<=4;i++) 
        {
            string str = zhuan(n.str, i);
            if (eMap.find(str) == eMap.end())
            {
                string sstep(n.step);
                sstep += i + '0';
                Node nn;
                nn.stepNum = n.stepNum + 1;
                nn.str = str;
                nn.step = sstep;
                q.push(nn);
                eMap[str] = sstep;
            }
        }
    }
}

void bfsStart(string str) 
{
    while (!q.empty())
        q.pop();
    Node n;
    n.step = "";
    n.stepNum = 0;
    n.str = str;
    q.push(n);
    int okStep = INT32_MAX;
    while (!q.empty())
    {
        n = q.top();
        q.pop();
        if (ok && n.stepNum != okStep)
            break;
        if (eMap.find(n.str) != eMap.end())
        {
            if (ok == 0)
            {
                curStep = n.step+path(eMap.find(n.str)->second);
                okStep = n.stepNum;
                ok = 1;
            }
            else
            {
                string step = n.step + path(eMap.find(n.str)->second);
                //判断大小
                if (strcmp(curStep.c_str(), step.c_str()) > 0)
                    curStep = step;
            }
        }
        if (ok)
            continue;
        for (int i = 1; i <= 4 && n.stepNum != 8; i++) 
        {
            str = zhuan(n.str,i);
            if (sMap.find(str) == sMap.end())
            {
                string sstep(n.step);
                sstep += i + '0';
                Node nn;
                nn.stepNum = n.stepNum + 1;
                nn.str = str;
                nn.step = sstep;
                sMap[str] = sstep;
                q.push(nn);
            }
        }
    }

}
int main()
{
    
    int k = 0;
    cin >> k;
    eMap.clear();
    bfsEnd();
    while (k--)
    {
        ok = 0;
        sMap.clear();
        string str = "";
        int j;
        for (int i = 0;i < MAXN;++i)
        {
            cin >> j;
            if (j == 10)
                str += 'a';
            else
                str += j + '0';
        }
        
        if (str == endState)
        {
            cout << "PUZZLE ALREADY SOLVED" << endl;
            continue;
        }
        bfsStart(str);
        if (ok==0)
        {
            cout << "NO SOLUTION WAS FOUND IN 16 STEPS" << endl;
            continue;
        }
        cout << curStep << endl;
        
    }

}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9823155.html