玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=<N<=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1
分析:想了半天才想到利用BFS求解最快可行解,13个数字并行找,找到第一个满足条件的输出。注意需要特判根本没有2012的,由于BFS消耗的空间比较大,需要注意利用map记录一下查找过的数字,同时只要朝着一个方向找就行。
代码:
/*DEBUG方法:输出,试数调错
找数据范围极限判断特例
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
char s[14];
int num;
};
map<ll,int>ma;
const int INF = 0x3f3f3f3f;
bool judge(node x)
{
int len = strlen(x.s);
for(int i = 0; i < len - 3; i++)
{
if(x.s[i] == '2' && x.s[i + 1] == '0' && x.s[i + 2] == '1' && x.s[i + 3] == '2')
{
return true;
}
}
return false;
}
ll cal(node x)
{
ll sum = 0;
for(int i = 0; i < strlen(x.s); i++)
{
sum = sum * 10 + x.s[i] - '0';
}
return sum;
}
void bfs()
{
ma.clear();
queue<node>que;
while(!que.empty())
{
que.pop();
}
node x;
char s[14];
scanf("%s",s);
if(strlen(s) < 4)
{
printf("-1\n");
return ;
}
int cnt0 = 0,cnt1 = 0,cnt2 = 0;
for(int i = 0; i < strlen(s); i++)
{
if(s[i] == '0')
{
cnt0++;
}
else if(s[i] == '1')
{
cnt1++;
}
else
{
cnt2++;
}
}
if(!(cnt2 >= 2 && cnt1 >= 1 && cnt0 >= 0))
{
printf("-1\n");
return;
}
strcpy(x.s,s);
x.num = 0;
que.push(x);
ma[cal(x)] = 1;
int len = strlen(s);
while(!que.empty())
{
node top = que.front();
ma[cal(top)] = 1;
// printf("%s\n",top.s);
que.pop();
if(judge(top))
{
printf("%d\n",top.num);
return;
}
for(int i = 0; i < len; i++)
{
node tmp;
if(!i)
{
char stmp[14];
strcpy(stmp,top.s);
swap(stmp[i],stmp[i + 1]);
strcpy(tmp.s,stmp);
tmp.num = top.num + 1;
if(!ma[cal(tmp)])
{
que.push(tmp);
}
}
else if(i == len - 1)
{
char stmp[14];
strcpy(stmp,top.s);
swap(stmp[i - 1],stmp[i]);
strcpy(tmp.s,stmp);
tmp.num = top.num + 1;
que.push(tmp);
if(!ma[cal(tmp)])
{
que.push(tmp);
}
}
else
{
node tmpl,tmpr;
char stmpl[14],stmpr[14];
//strcpy(stmpl,top.s);
strcpy(stmpr,top.s);
//swap(stmpl[i],stmpl[i - 1]);
swap(stmpr[i],stmpr[i + 1]);
//strcpy(tmpl.s,stmpl);
strcpy(tmpr.s,stmpr);
//tmpl.num = top.num + 1;
tmpr.num = top.num + 1;
//que.push(tmpl);
que.push(tmpr);
/*if(!ma[cal(tmpl)])
{
que.push(tmpl);
}*/
if(!ma[cal(tmpr)])
{
que.push(tmpr);
}
}
}
}
printf("-1\n");
}
int main()
{
int n;
while(~scanf("%d",&n))
{
bfs();
}
return 0;
}