题目链接:hdu 5402 Travelling Salesman Problem
当n和m均为偶数,需要舍掉一个偶数位的格子。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int dir[2][4][2] = { {{0, -1}, {-1, 0}, {1, 0}, {0, 1}}, {{-1, 0}, {0, 1}, {0, -1}, {1, 0}} };
const char sig[2][5] = {"LUDR", "URLD"};
int N, M, A[maxn][maxn], V[maxn][maxn];
char str[maxn * maxn];
int build (const int d[4][2], const char* t) {
int x = 1, y = 1, n = 0; V[1][1] = 1;
while (true) {
bool flag = true;
for (int i = 0; i < 4 && flag; i++) {
int p = x + d[i][0];
int q = y + d[i][1];
if (p <= 0 || p > N || q <= 0 || q > M || V[p][q])
continue;
str[n++] = t[i]; V[p][q] = 1;
x = p, y = q, flag = false;
}
if (flag) break;
}
str[n] = '\0';
if (x == N && y == M)
return n;
return 0;
}
void build2 (const int d[4][2], const char* t, int& x, int &y, int& n, int l, int r) {
V[x][y] = 1;
while (true) {
// printf("%d %d\n", x, y);
bool flag = true;
for (int i = 0; i < 4 && flag; i++) {
int p = x + d[i][0];
int q = y + d[i][1];
if (p <= 0 || p > N || q <= l || q > r || V[p][q])
continue;
str[n++] = t[i]; V[p][q] = 1;
x = p, y = q, flag = false;
}
if (flag) break;;
}
// printf("end:%d %d\n", x, y);
}
int main () {
while (scanf("%d%d", &N, &M) == 2) {
memset(V, 0, sizeof(V));
int k = 1e4 + 5, rx, ry, s = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
scanf("%d", &A[i][j]);
s += A[i][j];
if (A[i][j] < k && ((i+j)&1)) {
k = A[i][j];
rx = i, ry = j;
}
}
}
int end = N * M - 1;
if ((N&1) == 0 && (M&1) == 0) {
s -= k;
int x = 1, y = 1, n = 0;
memset(V, 0, sizeof(V));
V[rx][ry] = 1;
for (int i = 1; i <= M; i += 2) {
if (i == ry || i + 1 == ry)
build2(dir[1], sig[1], x, y, n, y - 1, y + 1);
else
build2(dir[0], sig[0], x, y, n, y - 1, y + 1);
y++;
str[n++] = 'R';
}
str[n-1] = '\0';
} else {
memset(V, 0, sizeof(V));
int n = build(dir[0], sig[0]);
if (n != end) {
memset(V, 0, sizeof(V));
int n = build(dir[1], sig[1]);
}
}
printf("%d\n%s\n", s, str);
}
return 0;
}