题目1482:玛雅人的密码
使用BFS宽搜
循环将输入的字符串相邻的两个字母交换,并将新得到的字符串与其交换步数插入到队列中,当队列中不为空时,取出队头
并用队头的字符串重复上述步骤
停止条件为如果字符串中出现“2012”则返回步数
因为搜索是步数从小到大逐层递增的,所以返回的一定是最少的步数
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <queue>
#include <map>
using namespace std;
map <string, int> visitMap;
map <string, int>::iterator it;//it是迭代器,指向关联容器
struct Node{
char arr[14];
int step;
};
Node node;
int N;
string tempstr;
bool Judge(char str[])
{
int i;
for(i = 0; i < N-3; i++)
if(str[i] == '2' && str[i+1] == '0' && str[i+2] == '1' && str[i+3] == '2')
return true;
return false;
}
void swap(char *str,int i,int j)
{
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
}
int BFS()
{
queue<Node> Q;
while(!Q.empty())
Q.pop();
Q.push(node);
while(!Q.empty())
{
node = Q.front();
Q.pop();
if(Judge(node.arr))
return node.step;
tempstr = node.arr;
it = visitMap.find(node.arr);
if(it == visitMap.end() || it->second == 0)//visitMap.end()指向容器的尾部,无实际元素
visitMap.insert(make_pair(tempstr,1));
char *newstr;
newstr = new char[tempstr.size()];
for(int i = 0; i < N-1;i++)
{
strcpy(newstr,node.arr);
swap(newstr,i,i+1);//交换字母
tempstr = newstr;
it = visitMap.find(tempstr);
if(it == visitMap.end() || it->second == 0)
{
visitMap.insert(make_pair(tempstr,1));
Node tmp;
tmp.step = node.step + 1;
strcpy(tmp.arr,newstr);
Q.push(tmp);
}
}
}
return -1;
}
int main()
{
while(cin>>N)
{
char str[14];
scanf("%s",&str);
if(N < 4)
{
printf("-1\n");
continue;
}
visitMap.clear();
node.step = 0;
strcpy(node.arr,str);
printf("%d\n",BFS());
}
return 0;
}