我先贴一下我的代码,等一下看你写的代码
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
const int step[8][2] = {{-1, -2}, {1, -2}, {-2, -1}, {2, -1}, {-2, 1}, {2, 1}, {-1, 2}, {1, 2}};
size_t array[8][8];
bool verify(void) {
for(size_t y = 0; y < 8; ++y) {
for(size_t x = 0; x < 8; ++x) {
if(!array[y][x]) return false;
}
}
return true;
}
bool exist(size_t x, size_t y) {
if(x >= 8) return false;
if(y >= 8) return false;
return true;
}
bool run(size_t x, size_t y, size_t count) {
if(verify()) return true;
if(!exist(x, y)) return false;
if(array[y][x]) return false;
bool flag = false;
array[y][x] = count;
for(size_t i = 0; i < 8; ++i) {
size_t nx = x + step[i][0];
size_t ny = y + step[i][1];
if((flag = run(nx, ny, count + 1))) break;
}
if(!flag) array[y][x] = 0;
return flag;
}
int main(void) {
time_t begin = time(NULL);
run(2, 0, 1);
for(size_t y = 0; y < 8; ++y) {
for(size_t x = 0; x < 8; ++x) {
printf("%2lu ", array[y][x]);
}
puts("");
}
time_t end = time(NULL);
printf("time: %lu\n", end - begin);
return 0;
}
$ gcc -O3 -o main main.c
$ ./main
11 4 1 18 9 6 15 64
2 19 10 5 14 17 24 7
39 12 3 20 23 8 63 16
30 21 38 13 28 25 46 61
37 40 29 22 47 62 51 26
34 31 36 55 52 27 60 45
41 56 33 48 43 58 53 50
32 35 42 57 54 49 44 59
time: 496
$
O3 优化都 496 秒,^_^
对于我的这个代码,第一次选的是题目中的位置$ gcc -O3 -o main main.c
$ ./main
6 3 8 11 14 17 20 23
9 12 5 2 21 24 15 18
4 7 10 13 16 19 22 25
31 28 41 36 1 26 49 38
42 35 30 27 40 37 60 47
29 32 55 44 61 48 39 50
54 43 34 57 52 63 46 59
33 56 53 62 45 58 51 64
time: 22
$
O3 优化,22 秒
这个使用时间的多少,和起点的选择有关
还和step数组中的元素排列顺序有关
想要得到一个用时最短的组合(起点和step数组中的元素排列顺序)
需要对每一个起点去尝试step数组的全排列,这需要相当长的时间
我就不找这个组合了
我试了一下答案,6秒#include <stdio.h>
#include <time.h>
#define X 8
#define Y 8
int chess[X][Y];
// 找到下一个可走的位置
int next(int *px, int *py, int count)
{
int x = *px;
int y = *py;
switch(count)
{
case 0:
if (x+2<=X-1 && y-1>=0 && chess[x+2][y-1] == 0)
{
*px = x + 2;
*py = y - 1;
return 1;
}
break;
case 1:
if (x+2<=X-1 && y+1<=Y-1 && chess[x+2][y+1] == 0)
{
*px = x + 2;
*py = y + 1;
return 1;
}
break;
case 2:
if (x+1<=X-1 && y-2>=0 && chess[x+1][y-2] == 0)
{
*px = x + 1;
*py = y - 2;
return 1;
}
break;
case 3:
if (x+1<=X-1 && y+2<=Y-1 && chess[x+1][y+2] == 0)
{
*px = x + 1;
*py = y + 2;
return 1;
}
break;
case 4:
if (x-2>=0 && y-1>=0 && chess[x-2][y-1] == 0)
{
*px = x - 2;
*py = y - 1;
return 1;
}
break;
case 5:
if (x-2>=0 && y+1<=Y-1 && chess[x-2][y+1] == 0)
{
*px = x - 2;
*py = y + 1;
return 1;
}
break;
case 6:
if (x-1>=0 && y-2>=0 && chess[x-1][y-2] == 0)
{
*px = x - 1;
*py = y - 2;
return 1;
}
break;
case 7:
if (x-1>=0 && y+2<=Y-1 && chess[x-1][y+2] == 0)
{
*px = x - 1;
*py = y + 2;
return 1;
}
break;
}
return 0;
}
int setHorse(int x, int y, int tag)
{
int x1 = x, y1 = y, flag = 0, count = 0;
// tag记录轨迹
chess[x][y] = tag;
// 如果tag等于64退出程序
if (tag == X*Y)
{
return 1;
}
// 如果可以走,那么flag为1
flag = next(&x1, &y1, count);
// 否则尝试其他路径
while (flag == 0 && count < 7)
{
count += 1;
flag = next(&x1, &y1, count);
}
// 递归进入下一个坐标
while (flag)
{
// 返回1表示成功找到落脚点
if (setHorse(x1, y1, tag+1))
{
return 1;
}
// 否则从上一步重新尝试
x1 = x;
y1 = y;
count += 1;
flag = next(&x1, &y1, count);
while (flag == 0 && count < 7)
{
count += 1;
flag = next(&x1, &y1, count);
}
}
if (flag == 0)
{
chess[x][y] = 0;
}
return 0;
}
int main(void)
{
time_t begin = time(NULL);
int i, j;
for (i = 0; i < X; i++)
{
for (j = 0; j < Y; j++)
{
chess[i][j] = 0;
}
}
// 讲道理,从 (2, 0) 坐标开始计算是比较容易出结果的
// 如果你比较有耐心,或 CPU 特别强劲,可以尝试计算其它坐标
if (setHorse(2, 0, 1))
{
for (i = 0; i < X; i++)
{
for (j = 0; j < Y; j++)
{
printf("%02d ", chess[i][j]);
}
putchar('\n');
}
}
else
{
printf("可惜无解!\n");
}
time_t end = time(NULL);
printf("time: %lu\n", end - begin);
return 0;
}
$ gcc -O3 -o tmp tmp.c
$ ./tmp
43 50 47 38 57 52 61 32
48 37 44 51 46 33 58 53
01 42 49 56 39 60 31 62
36 15 40 45 34 29 54 59
41 02 35 16 55 24 63 30
14 05 12 09 22 19 28 25
03 10 07 20 17 26 23 64
06 13 04 11 08 21 18 27
time: 6
$
|