在图中的九个点上,空出中间的点,其余的点上任意填入数字1到8。1的位置固定不动,然后移动其余的数字,使1到8顺时针从小到大排列。移动的规律是:只能将数字沿线移向空白的点.请编程显示数字移动过程。
也可以看成是一个圆形(环形):
先阅读下面的程序:
#include<stdio.h>
//查找环形数据坐标的前后坐标
int get(int row,int col,int direction)
{
int a[]= {0,1,2,12,22,21,20,10};
int i;
for(i=0; i<8; i++)
if(a[i]==row*10+col)
return a[(i+direction+8)%8];
}
//查找data所在行列
int getdata(int a[3][3],int data)
{
int i,j;
for(i=0; i<3; i++)
for(j=0; j<3; j++)
if(a[i][j]==data)
return i*10+j;
}
int print(int a[3][3])
{
int i,j;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++) printf("%2d",a[i][j]);
printf("\n");
}
}
int main()
{
int a[3][3]=
{
2,8,5,
6,0,4,
3,1,7
};
int i,j,k,pos;
int row,col;
int count=0;
printf("移动前的数据:\n");
print(a);
for(i=2; i<=8; i++)
{
pos=getdata(a,i);//查找数值i的坐标
row=pos/10;//i的坐标
col=pos%10;//i的坐标
a[1][1]=i;
a[row][col]=0;
pos=get(row,col,-1);//查找数值i的前一个数的坐标
while(a[pos/10][pos%10]!=i-1)
{
a[row][col]=a[pos/10][pos%10]; //前一个数放在数据0位置
a[pos/10][pos%10]=0;//前一个数改成0
row=pos/10;col=pos%10;
pos=get(pos/10,pos%10,-1);//查找下一个
count++;
//printf("\n");print(a); 输出中间过程
}
a[row][col]=i;
a[1][1]=0;
}
printf("移动后的数据:\n");
print(a);
printf("移动次数:%d\n",count);
}
分析:
int get(int row,int col,int direction)函数根据给出的坐标,查找环形数据前后的坐标;
int getdata(int a[3][3],int data) 函数查找data所在的坐标;
函数返回的坐标采用row*10+col的方式,十位数为行,个位数是列。
主函数从2开始查找,具体步骤如下:
(1)找到i的坐标(i=2~8)
(2)将i和中心值交换
(3)计算前一个数(逆时针direction等于-1,顺时针direction等于1)的坐标,若前一个数是i-1,终止查找,将i填入空值位置;如果不是,将前一个数和i所在位置交换(i已经放在中心,相当于临时存储),再将前一个数对应的位置置为0。
运行结果: