问 THUWC 2024 四子棋
  • 板块学术版
  • 楼主xxxxxzy
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/1/11 19:49
  • 上次更新2025/1/11 22:59:02
查看原帖
问 THUWC 2024 四子棋
770611
xxxxxzy楼主2025/1/11 19:49

今天上午开始写,然后写到中午,差不多在 https://www.saiblo.net 上面过了 73 个点上下。

然后下午一直就突破不了,一直在 73 上下徘徊。

写的爆搜,然后对所有无法确定的情况估价,我的爆搜大约能跑 7 层(单),求问有没有佬能告诉我接下来要怎么卡。

αβ\alpha-\beta 剪枝感觉很玄学,而且感觉最多优化一两层,有同学写了甚至有时打不过我的爆搜;那个蒙啥啥树机房也有人写,不过跑得都比较废物,这两个都没加,因为个人不太清楚有没有太大用。

放个代码:

下错位置是正常的,只有当爆搜到必输情况才会出现。

#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);
    }
}
2025/1/11 19:49
加载中...