智力题, 跟 曼哈顿距离的奇偶性有关。
国际象棋棋盘上, 假设从一个黑色格子出发,要经过若干步走到某个白色格子(每步只能上下左右4个方向之一),步数肯定是奇数。
#include <cstdio>
#include <vector>
using namespace std;
int N;
//===========================================================
//移除一层
void moveAndRemove(int moves, int start, int len) {
int i;
int a = start, b = a + len - 1;
int c = b + N * (len - 1), d = a + N * (len - 1);
printf("%d", moves);
moves += 2;
for (i = a; i <= b; i += 2) printf(" %d", i);
for (i = d; i <= c; i += 2) printf(" %d", i);
for (i = a + 2 * N; i < d; i += 2 * N) printf(" %d", i);
for (i = b + 2 * N; i < c; i += 2 * N) printf(" %d", i);
printf("\n");
printf("%d", moves);
moves += 2;
for (i = a + 1; i < b; i += 2) printf(" %d", i);
for (i = d + 1; i < c; i += 2) printf(" %d", i);
for (i = a + N; i < d; i += 2 * N) printf(" %d", i);
for (i = b + N; i < c; i += 2 * N) printf(" %d", i);
printf("\n");
// start = start + 1 + N;
// len = len - 2;
}
void handleInCaseOfEvenN(int moves, int len) {
printf("%d", moves);
moves += 2;
int a = 1;
int b = 1 + len - 1;
int c = 1 + N * (len - 1);
int i;
for (i = a; i < b; i += 2) printf(" %d", i);
for (i = a + 2 * N; i < c; i += 2 * N) printf(" %d", i);
printf("\n");
printf("%d", moves);
moves += 2;
for (i = a + 1; i <= b; i += 2) printf(" %d", i);
for (i = a + N; i <= c; i += 2 * N) printf(" %d", i);
printf("\n");
}
int main() {
int moves;
int len;
int start;
scanf("%d", &N);
if (N == 2) {
printf("3 1\n");
printf("5 2\n");
printf("7 4\n");
return 0;
}
if (N % 2 == 0) {
moves = N + 1;
handleInCaseOfEvenN(moves, N);
moves += 4;
len = N - 1;
start = 1 + 1 + N;
while(1) {
moveAndRemove(moves, start, len);
moves += 4;
start = start + 1 + N;
len = len - 2;
if (len == 1) break;
}
} else {
moves = N;
len = N;
start = 1;
while(1) {
moveAndRemove(moves, start, len);
moves += 4;
start = start + 1 + N;
len = len - 2;
if (len == 1) break;
}
}
return 0;
}