/*
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[n];
result[n]=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[n];
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;
}