您的位置:首页 > 其它

蓝桥杯BFS 移动方格的问题

2014-07-21 14:22 344 查看
这道题好像是某一届高职高专的最后一题,原题如下:
/*
10. 移动字母
2x3=6个方格中放入ABCDE五个字母,右下角的那个格空着。如图1所示。
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的C和E就可以移动,移动后的局面分别是:
A B
D E C

A B C
D E

为了表示方便,我们把6个格子中字母配置用一个串表示出来,比如上边的两种局面分别表示为:
AB*DEC
ABCD*E
题目的要求是:请编写程序,由用户输入若干表示局面的串,程序通过计算,输出是否能通过对初始状态经过若干次移动到达该状态。可以实现输出1,否则输出0。初始状态为:ABCDE*
用户输入的格式是:先是一个整数n,表示接下来有n行状态。程序输出也应该是n行1或0
例如,用户输入:
3
ABCDE*
AB*DEC
CAED*B

则程序应该输出:
1
1
0
*/

解题思路分析: 根据题目分析可知,每次能否移动某个方格的关键就是* 的位置,根据*的不同位置有不同的移动方法,而且每次移动可能都能有新的状态产生,当然可能会重复,由于每次都只能和* 相邻的位置元素交换而且要避免和前面的已经有过的状态重复,所以我当时拿到题目使用的是BFS搜索,我的思路是这样的:

首先我有一个队列,(char queue[710][6]; // 定义一个队列 总共排列710 总不可能超过710总情况),初始时放入ABCDE* 开始队列下标index指向初始情况队列总数countqueue=1如图:


开始的排列:


所以可以将2号和5号对换 得到 AB*DEC (没有出现过,入队列),也可以将4号和5号兑换 得到ABCD*E(没有出现 ,入队列)

此时队列的情况:


经过一次变化之后index加1 countqueue=3指向AB*DEC


此时可以将1,2 或则 2,5对换分别得到A*BDEC(没出现,入队列) 和 ABCDE*(重复,舍去)此次操作之后队列的index为2,countqueue=4:,如下图:



按照此步奏不断的重复 知道 index>=countqueue循环截止

程序代码如下(打印出所有可能移到的结果):

#include <cstdlib>
#include <iostream>
#include<algorithm>
//  蓝桥杯移动方格的问题
using namespace std;
char queue[710][6];  // 定义一个队列
int countqueue;  // 记录队列的长度
int getIndex(char *a)  // 找到* 的下标
{   int result=0;
for(int i=0;i<6;i++)
if(a[i]=='*')
{
result=i;
break;
}
return result;
}
bool equals(char *a,char *b)  // 判断两个字符串是否相等
{
bool sign=true;
for(int i=0;i<6;i++)
if(a[i]!=b[i])
{
sign=false;
break;
}
return sign;
}
bool inQueue(char *a)  // 判断字符串是否存在队列中
{
bool sign=false;  // 不存在
for(int i=0;i<countqueue;i++)
if(equals(a,queue[i]))
{
sign=true;  // 存在
break;
}
return sign;
}
void pushqueue(char *a)  // 进队列
{
for(int i=0;i<6;i++)
queue[countqueue][i]=a[i];
countqueue++;
}
char* swap(char* a,int m,int n) // 将m,n 下标的字符对换
{
char* result=new char[6];
for(int i=0;i<6;i++)
result[i]=a[i];
char t=result[m];
result[m]=result
;
result
=t;
return result;
}

void getAllPerm()  // 得到所有的排列
{
int i=0;
while(i<countqueue)
{
int index=getIndex(queue[i]);  // 得到当前串中* 的下标
char* swapchar;  // 通过交换得到的字符串
switch(index)   //  根据* 号的下标  进行字符串的交换
{

case 0:	swapchar=swap(queue[i],0,1);
if(!inQueue(swapchar))  // 如果字符串不在队列中,则加入到队列中
pushqueue(swapchar);
swapchar=swap(queue[i],0,3);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
case 1: swapchar=swap(queue[i],0,1);

if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],2,1);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],4,1);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
case 2:
swapchar=swap(queue[i],2,1);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],2,5);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
case 3:	swapchar=swap(queue[i],3,0);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],3,4);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
case 4: swapchar=swap(queue[i],4,1);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],4,3);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],4,5);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
case 5:	swapchar=swap(queue[i],5,4);
if(!inQueue(swapchar))
pushqueue(swapchar);
swapchar=swap(queue[i],5,2);
if(!inQueue(swapchar))
pushqueue(swapchar);
break;   //  错误 原因
}
i++;
}
}
int main(int argc, char *argv[])
{
int n;
char a[7]="abcde*";
pushqueue(a);
getAllPerm();
cout<<"print: queue"<<endl;
for(int i=0;i<countqueue;i++)
{
for(int j=0;j<6;j++)
cout<<queue[i][j]<<"  ";
cout<<endl;
}
cout<<"共有"<<countqueue<<"条合格的记录"<<endl;
cin>>n;
int *result=new int
;
for(int i=0;i<n;i++)
{
char test[6];
fflush(stdin);
for(int j=0;j<6;j++)
cin>>test[j];
if(inQueue(test))
result[i]=1;
else
result[i]=0;
}
for(int i=0;i<n;i++)
{
cout<<result[i]<<endl;
}

/*
cout<<"print: queue"<<endl;
for(int i=0;i<countqueue;i++)
{
for(int j=0;j<6;j++)
cout<<queue[i][j]<<"  ";

cout<<endl;
}*/
system("pause");
return EXIT_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: