只加了先搜第一行第一列和最优性剪枝俩优化,1 ~ 5 正确,6 就 WA 掉了,求大佬帮忙看看 Orz
#include <vector>
#include <iomanip>
using namespace std;
const int S = 15;
typedef pair<int, int> P;
int n, a[S][S];
int ans[S][S], mns = 5050;
bool h[205], vis[105], ok = false;
int tot;
//vector<int> p;
vector<int> nxt[105];
vector<int> cab[10105];
void sieve() {
h[1] = true;
for (int i = 2; i <= 200; i++) {
if (!h[i]) {
// p.push_back(i);
for (int j = 2 * i; j <= 200; j += i) {
h[j] = true;
}
}
}
}
void dfs(int x, int y) {
if (x == n + 1 && y == 2) {
ok = true;/*
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << a[i][j] << ' ';
}
cout << endl;
}*/
mns = tot;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
ans[i][j] = a[i][j];
}
}
}
if (x == 1) { // the first line
int pre = a[x][y - 1];
for (auto i : nxt[pre]) {
if (!vis[i]) {
vis[i] = true;
a[x][y] = i;
tot += i;
if (y == n) {
dfs(2, 1);
} else {
dfs(x, y + 1);
}
vis[i] = false;
a[x][y] = 0;
tot -= i;
}
}
} else if (y == 1) { // the first column
int pre = a[x - 1][y];
for (auto i : nxt[pre]) {
if (!vis[i]) {
vis[i] = true;
a[x][y] = i;
tot += i;
if (x == n) {
if (tot >= mns) {
return;
} else {
dfs(2, 2);
}
} else {
dfs(x + 1, y);
}
vis[i] = false;
tot -= i;
a[x][y] = 0;
}
}
} else {
int lft = a[x - 1][y], up = a[x][y - 1];
if (lft > up) {
swap(up, lft);
}
int pre = lft * 100 + up;
for (auto i : cab[pre]) {
if (!vis[i]) {
vis[i] = true;
a[x][y] = i;
if (y == n) {
dfs(x + 1, 2);
} else {
dfs(x, y + 1);
}
vis[i] = false;
a[x][y] = 0;
}
}
}
}
int main() {
cin >> n;
sieve();
for (int i = 1; i <= n * n; i++) {
for (int j = 1; j <= n * n; j++) {
if (i != j) {
if (!h[i + j]) {
nxt[i].push_back(j);
}
}
}
}/*
for (int i = 1; i <= n * n; i++) {
cout << i << ": ";
for (auto v : nxt[i]) {
cout << v << ' ';
}
cout << endl;
}*/
bool ext1[105], ext2[105];
for (int i = 1; i <= n * n; i++) {
for (int j = i + 1; j <= n * n; j++) {
for (int k = 1; k <= n * n; k++) {
ext1[k] = false;
ext2[k] = false;
}
for (auto v : nxt[i]) {
ext1[v] = true;
}
for (auto v : nxt[j]) {
ext2[v] = true;
}
int cob = i * 100 + j;
// cout << cob << ": ";
for (int k = 1; k <= n * n; k++) {
if (ext1[k] && ext2[k]) {
cab[cob].push_back(k);
// cout << k << ' ';
}
}
// cout << endl;
}
}
a[1][1] = 1;
vis[1] = true;
dfs(1, 2);
if (!ok) {
cout << "NO";
return 0;
}
cout << mns << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << ans[i][j] << ' ';
}
cout << endl;
}
return 0;
}