《面向计算机科学的离散数学B》
第一周作业补充题
—————————————-
题目
—————————————-
思路
这道题应该是有基于图论的数学解法的,暂时没想到,想到了再更新。
目前采用的方法是从初始状态开始编程遍历所有可能的情况。
预处理:
马只能在九宫格周围8个方格跳。将8个方格从左上角开始按顺时针方向顺序编号0~7。马的跳动用(+-3)表示。4匹马按顺序依次跳,形成四重循环。
—————————————-
代码
// 能否让马跳动几次(不考虑别马腿),将左图所示的阵势变为右图所示的阵势?
// 白 ** 白 白 ** 黑
// ** ** ** ** ** **
// 黑 ** 黑 黑 ** 白
//
// 解法:将棋盘从左上角开始按顺时针顺序编号,从初始状态(0,2;4,6)开始遍历所有可能,看看是否会出现(0,4;2,6) or (4,0;6,2)
#include<fstream>
using namespace std;
int main()
{
unsigned int h[4] = {0,2,4,6}; // h[0],h[1]: White; h[2],h[3]: black
int i=0, j=0, k=0, l=0;
ofstream out;
out.open("JumpHorse.txt");
for (i=0;i<8;i++) // 8次"+3"(跳马)一个循环
{
h[0] = (3*i)%8;
if(h[0]==2 || h[0]==4 || h[0]==6) // 左上角的白马先跳,约束为其他3匹马的初始位置
{
break;
}
for(j=0;j<8;j++)
{
h[1] = (2+3*j)%8;
if(h[1] == h[0] || h[1] == 4 || h[1] == 6) // 右上角的白马第二个跳,约束为2匹黑马的初始位置和第一匹白马的实时位置
{
break;
h[1] = 2;
}
for(k=0;k<8;k++)
{
h[2] = (4+3*k)%8;
if(h[2]==h[1] || h[2]==h[1] || h[2] == 6)// 右下角的黑马第三个跳,约束为最后一匹黑马的初始位置和2匹白马的实时位置
{
break;
h[2] = 4;
}
for(l=0;l<8;l++)
{
h[3] = (6+3*l)%8;
if(h[3]==h[2] || h[3]==h[1] || h[3]==h[0])// 左下角的黑马第四个跳,约束为前3匹马的实时位置
{
break;
h[3] = 6;
}
// printf("%d, %d; %d, %d",h[0],h[1],h[2],h[3]);
out << h[0] <<", "<< h[1] <<"; "<< h[2] <<", "<< h[3];
if(((h[0]==0&&h[1]==4) || (h[0]==4&&h[1]==0)) && ((h[2]==2&&h[3]==6) || (h[2]==6&&h[3]==2)))
{
out << " Found!" <<endl;
}
else
{
out << endl;
}
}
}
}
}
out.close();
return 0;
}
—————————————-
实验结果
0, 2; 4, 6
0, 2; 4, 1
0, 2; 7, 6
0, 2; 7, 1
0, 2; 7, 4
0, 5; 4, 6
0, 5; 4, 1
0, 5; 7, 6
0, 5; 7, 1
0, 5; 7, 4
0, 5; 2, 6
0, 5; 2, 1
0, 5; 2, 4
0, 5; 2, 7
3, 2; 4, 6
3, 2; 4, 1
3, 2; 7, 6
3, 2; 7, 1
3, 2; 7, 4
3, 5; 4, 6
3, 5; 4, 1
3, 5; 7, 6
3, 5; 7, 1
3, 5; 7, 4
3, 5; 2, 6
3, 5; 2, 1
3, 5; 2, 4
3, 5; 2, 7
3, 0; 4, 6
3, 0; 4, 1
3, 0; 7, 6
3, 0; 7, 1
3, 0; 7, 4
3, 0; 2, 6
3, 0; 2, 1
3, 0; 2, 4
3, 0; 2, 7
3, 0; 5, 6
3, 0; 5, 1
3, 0; 5, 4
3, 0; 5, 7
3, 0; 5, 2