今天上午开始写,然后写到中午,差不多在 https://www.saiblo.net 上面过了 73 个点上下。
然后下午一直就突破不了,一直在 73 上下徘徊。
写的爆搜,然后对所有无法确定的情况估价,我的爆搜大约能跑 7 层(单),求问有没有佬能告诉我接下来要怎么卡。
α−β 剪枝感觉很玄学,而且感觉最多优化一两层,有同学写了甚至有时打不过我的爆搜;那个蒙啥啥树机房也有人写,不过跑得都比较废物,这两个都没加,因为个人不太清楚有没有太大用。
放个代码:
下错位置是正常的,只有当爆搜到必输情况才会出现。
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define ld lower_bound
#define rep(i, a, b) for (int i = a; i < b; i++)
#define drep(i, a, b) for (int i = a; i > b; i--)
#define ud upper_bound
#define mem(s) memset(s, 0, sizeof(s))
#define fi first
#define se second
#define ull unsigned long long
using namespace std;
int noX, noY;
int lastX, lastY;
int N, M;
int c[100][100];
int* top;
inline bool judge(int x, int y, int col) {
if (x > 2 && c[x - 1][y] == col && c[x - 2][y] == col && c[x - 3][y] == col) return 1;
if (x < N - 1 && x > 1 && c[x + 1][y] == col && c[x - 1][y] == col && c[x - 2][y] == col) return 1;
if (x < N - 2 && x > 0 && c[x + 2][y] == col && c[x + 1][y] == col && c[x - 1][y] == col) return 1;
if (x < N - 3 && c[x + 3][y] == col && c[x + 2][y] == col && c[x + 1][y] == col) return 1;
if (y > 2 && c[x][y - 1] == col && c[x][y - 2] == col && c[x][y - 3] == col) return 1;
if (y < M - 1 && y > 1 && c[x][y + 1] == col && c[x][y - 1] == col && c[x][y - 2] == col) return 1;
if (y < M - 2 && y > 0 && c[x][y + 2] == col && c[x][y + 1] == col && c[x][y - 1] == col) return 1;
if (y < M - 3 && c[x][y + 3] == col && c[x][y + 2] == col && c[x][y + 1] == col) return 1;
if (x > 2 && y > 2 && c[x - 1][y - 1] == col && c[x - 2][y - 2] == col && c[x - 3][y - 3] == col) return 1;
if (x < N - 1 && x > 1 && y < M - 1 && y > 1 && c[x + 1][y + 1] == col && c[x - 1][y - 1] == col && c[x - 2][y - 2] == col) return 1;
if (x < N - 2 && x > 0 && y < M - 2 && y > 0 && c[x + 2][y + 2] == col && c[x + 1][y + 1] == col && c[x - 1][y - 1] == col) return 1;
if (x < N - 3 && y < M - 3 && c[x + 3][y + 3] == col && c[x + 2][y + 2] == col && c[x + 1][y + 1] == col) return 1;
if (x < N - 3 && y > 2 && c[x + 1][y - 1] == col && c[x + 2][y - 2] == col && c[x + 3][y - 3] == col) return 1;
if (x < N - 2 && x > 0 && y < M - 1 && y > 1 && c[x - 1][y + 1] == col && c[x + 1][y - 1] == col && c[x + 2][y - 2] == col) return 1;
if (x < N - 1 && x > 1 && y < M - 2 && y > 0 && c[x - 2][y + 2] == col && c[x - 1][y + 1] == col && c[x + 1][y - 1] == col) return 1;
if (x > 2 && y < M - 3 && c[x - 3][y + 3] == col && c[x - 2][y + 2] == col && c[x - 1][y + 1] == col) return 1;
return 0;
}
double bg, ed;
int limit;
int ans = 0;
vector <int> vec;
inline int dfs(int x, int f) {
rep (i, 0, M) {
if (top[i]) {
if (judge(top[i] - 1, i, f)) return i;
}
}
if (x >= limit) return -1;
int p = -1;
rep (i, 0, M) {
if (top[i]) {
top[i]--; c[top[i]][i] = f;
int k = dfs(x + 1, (f == 1 ? 2 : 1));
c[top[i]][i] = 0; top[i]++;
if (k == -2) return i;
if (k == -1 && x == 1) vec.pb(i);
if (k == -1) p = 1;
}
}
if (p != -1) return -1;
return -2;
}
mt19937 rd(time(0));
inline int f(int x, int y, int col) {
int L = x, R = x, fL = x, fR = x;
while (L > 0 && c[L - 1][y] == col) L--;
while (R < N - 1 && c[R + 1][y] == col) R++;
while (fL > 0 && (c[fL - 1][y] == col || c[fL - 1][y] == 0)) fL--;
while (fR < N - 1 && (c[fR + 1][y] == col || c[fR + 1][y] == 0)) fR++;
if (fR - fL + 1 <= 3) R = L = x;
double sum = min((R - L + 1), 4) * 1.5;
double ans = min((R - L + 1), 4) * 1.5;
fL = L = y, fR = R = y;
while (L > 0 && c[x][L - 1] == col) L--;
while (R < M - 1 && c[x][R + 1] == col) R++;
while (fL > 0 && (c[x][fL - 1] == col || c[x][fL - 1] == 0)) fL--;
while (fR < M - 1 && (c[x][fR + 1] == col || c[x][fR + 1] == 0)) fR++;
if (fR - fL + 1 <= 3) R = L = x;
ans = max(ans, (min((R - L + 1), 4) * 1.5));
sum += min((R - L + 1), 4) * 1.5;
fL = L = 0, fR = R = 0;
while (x > L && y > L && c[x - L - 1][y - L - 1] == col) L++;
while (x + R < N - 1 && y + R < M - 1 && c[x + R + 1][y + R + 1] == col) R++;
while (x > fL && y > fL && (c[x - fL - 1][y - fL - 1] == col || c[x - fL - 1][y - fL - 1] == 0)) fL++;
while (x + fR < N - 1 && y + fR < M - 1 && (c[x + fR + 1][y + fR + 1] == col || c[x + fR + 1][y + fR + 1] == 0)) fR++;
if (fL + fR <= 3) R = L = 0;
ans = max(ans, 1.0 * min(4, L + R)); sum += min(4, L + R);
L = R = fL = fR = 0;
while (x > L && y + L < M - 1 && c[x - L - 1][y + L + 1] == col) L++;
while (x + R < N - 1 && y > R && c[x + R + 1][y - R - 1] == col) R++;
while (x > fL && y + fL < M - 1 && (c[x - fL - 1][y + fL + 1] == col || c[x - fL - 1][y + fL + 1] == 0)) fL++;
while (x + fR < N - 1 && y > fR && (c[x + fR + 1][y - fR - 1] == col || c[x + fR + 1][y - fR - 1] == 0)) fR++;
if (fL + fR <= 3) R = L = 0;
ans = max(ans, 1.0 * min(4, L + R)); sum += min(4, L + R);
return max(0.0, sum * 0.8 + ans + (M - y) * 0.2);
}
int num_chess = 0;
inline pii solve() {
num_chess += 2;
limit = 7;
if (num_chess > 50) limit = 8;
vec.clear(); int k = dfs(1, 1);
if (k >= 0) return mp(top[k] - 1, k);
if (k == -1) {
double mx = -100;
int p = -1;
for (int i : vec) {
double d = f(top[i] - 1, i, 1) * 0.5 + f(top[i] - 1, i, 2) + min(i, abs(M - i + 1)) * 0.1;
if (d > mx) mx = d, p = i;
}
assert(p != -1);
return mp(top[p] - 1, p);
}
cerr << "lose\n";
if (k == -2) {
rep (i, 0, M) {
if (judge(top[i] - 1, i, 2)) return mp(top[i] - 1, i);
}
}
while (limit > 0 && k == -2) {
limit--;
vec.clear(); int k = dfs(1, 1);
if (k == -1) {
double mx = -100;
int p = -1;
for (int i : vec) {
double d = f(top[i] - 1, i, 1) + f(top[i] - 1, i, 1) + min(i, abs(M - i)) * 0.1;
if (d > mx) mx = d, p = i;
}
return mp(top[p] - 1, p);
}
}
while (1) {
int x = rd() % M;
if (!top[x]) continue;
return mp(top[x] - 1, x);
}
}
void send(const char *msg) {
size_t len = strlen(msg);
printf("%c%c%c%c%s", (unsigned char)(len >> 24), (unsigned char)(len >> 16), (unsigned char)(len >> 8), (unsigned char)(len), msg);
fflush(stdout);
}
int main() {
scanf("%d %d %d %d", &N, &M, &noX, &noY);
rep (i, 0, N) {
rep (j, 0, M) c[i][j] = 0;
}
c[noX][noY] = 3;
top = new int[M];
while (1) {
scanf("%d %d", &lastX, &lastY);
for(int i = 0; i < M; i ++) scanf("%d", &top[i]);
int x; pii point;
for(int i = 0; i < N * M; i ++) scanf("%d", &x);
if (lastX == -1 && lastY == -1) x = M / 2, point = mp(top[x] - 1, x);
else c[lastX][lastY] = 2, point = solve();
c[point.fi][point.se] = 1;
char msg[6];
sprintf(msg, "%d %d", point.fi, point.se);
send(msg);
}
}