题目描述
玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=<N<=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1。
输入描述:
输入包含多组测试数据,每组测试数据由两行组成。 第一行为一个整数N,代表字符串的长度(2<=N<=13)。 第二行为一个仅由0、1、2组成的,长度为N的字符串。
输出描述:
对于每组测试数据,若可以解出密码,输出最少的移位次数;否则输出-1。
解析:利用bfs的思想进行
代码如下:
方法一:bfs(纯C,无利用queue函数)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
char pass[]="2012";
typedef struct queue{
char str[15];
int deep;
struct queue *next;
}*LQueue;
int check(char *s,int n){
int i=0,j=0;
while(i<n&&j<4){
if(s[i]==pass[j]){
i++;
j++;
}else{
i=i-j+1;
j=0;
}
}
if(j==4)
return 1;
return 0;
}
int func(char *s,int n){
int n0=0,n1=0,n2=0,i=0;
for(i=0;i<n;i++){
if(s[i]=='0')
n0++;
else if(s[i]=='1')
n1++;
else if(s[i]=='2')
n2++;
}
if(n0>0&&n1>0&&n2>1)
return 1;
return 0;
}
int main(){
int n=0,i=0,result=0;
char str[15],t=0;
while(~scanf("%d",&n)){
scanf("%s",str);
LQueue head=(queue *)malloc(sizeof(queue));
LQueue rear=head;
strncpy(head->str,str,n);
head->deep=0;
if(func(str,n)==0)
result=-1;
else{
while(check(str,n)==0){
for(i=0;i<n-1;i++){
LQueue p=(queue *)malloc(sizeof(queue));
strncpy(p->str,str,n);
t=p->str[i];
p->str[i]=p->str[i+1];
p->str[i+1]=t;
p->deep=head->deep+1;
rear->next=p;
rear=p;
}
head=head->next;
strncpy(str,head->str,n);
}
result=head->deep;
}
printf("%d\n",result);
}
return 0;
}
方法二:bfs利用C++函数库的queue实现
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
using namespace std;
struct node{
char str[15];
int deep;
};
queue<node> Q;
int bfs(int n){
int i,j;
node tmp,p=Q.front();
char x;
for(i=0;i<n;i++){
if(p.str[i]=='2'&&p.str[i+1]=='0'&&p.str[i+2]=='1'&&p.str[i+3]=='2')
return p.deep;
}
while(Q.empty()==false){
p=Q.front();
Q.pop();
for(i=0;i<n;i++){
strcpy(tmp.str,p.str);
x=tmp.str[i];
tmp.str[i]=tmp.str[i+1];
tmp.str[i+1]=x;
tmp.deep=p.deep+1;
Q.push(tmp);
for(j=0;j<n;j++)
if(tmp.str[j]=='2'&&tmp.str[j+1]=='0'&&tmp.str[j+2]=='1'&&tmp.str[j+3]=='2')
return tmp.deep;
}
}
return -1;
}
int ok(char *a,int n){
int i,n0=0,n1=0,n2=0;
for(i=0;i<n;i++){
if(a[i]=='0')
n0++;
else if(a[i]=='1')
n1++;
else if(a[i]=='2')
n2++;
}
if(n0>0&&n1>0&&n2>1)
return 1;
return 0;
}
int main(){
int n;
char a[15];
while(~scanf("%d",&n)){
scanf("%s",a);
if(ok(a,n)==0){
printf("-1\n");
continue;
}
while(Q.empty()==false)
Q.pop();
node p;
strcpy(p.str,a);
p.deep=0;
Q.push(p);
int res=bfs(n);
printf("%d\n",res);
}
return 0;
}