2x3=6个方格中放入ABCDE五个字母,右下角的那个格空着。如图1所示。在格子中移动字母
_________________
|__A__|__B__|__C__|
|__D__|__E__|_____|
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的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
_________________
|__A__|__B__|__C__|
|__D__|__E__|_____|
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的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
分析:
我们将每个输入的字符串进行递归转换,每次转换与原始状态ABCDE*比较看是否相等。递归实现:我们从空格出发,将空格当作移动的对象,每次都可以前后左右移动,每移动一次,都要与原字符串比较一次看是否相等。
代码如下:
#include<stdio.h>
#include<string.h>
int vis[6];//用于标记路径是否走过
int TF[100],count;//用于保存每个字符串结果
char temp[]="ABCDE*";//要比较的字符串
void Getstar(char array[],int *row,int *column)//获得空格*的横纵坐标
{
for (int i = 0; i < 6; i++)
{
if (array[i] == '*')
{
*row = i - 3 < 0 ? 0 : 1;
*column = i % 3;
}
}
}
void Print(int n)//输出结果
{
for (int i = 0; i < n; i++)
{
printf("%d\n",TF[i]);
}
}
void swap(char *a,char *b)//交换位置
{
char T = *a;
*a = *b;
*b = T;
}
void fun(char *cur,int row,int column)//递归求解
{
int i,x,y;
int a[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//前后左右移动
if(!strcmp(cur,temp))
{
TF[count] = 1;
return;
}
else
{
for(i = 0; i < 4; i++)//每次空格可以前后左右移动
{
x = row + a[i][0];
y = column + a[i][1];
if((x >= 0 && x <= 1) && (y >= 0 && y <= 2) && !vis[3 * x + y])//如果存在此点且未被访问
{
swap(cur + 3 * row + column,cur + 3 * x + y);
vis[3 * x + y] = 1;
fun(cur,x,y);
swap(cur + 3 * row + column,cur + 3 * x + y);//要恢复原来状态,避免影响后面运算
vis[3 * x + y] = 0;
}
}
}
}
int main()
{
int n,row,column,i;
char array[7];
scanf("%d",&n);
i = n;
while (i)
{
scanf("%s",array);
Getstar(array,&row,&column);
fun(array,row,column);
count++;
i--;
}
Print(n);
return 0;
}