求助DLX模板(关注悬赏)
  • 板块UVA1309 Sudoku
  • 楼主Kalium
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/3/5 13:58
  • 上次更新2023/10/23 22:59:24
查看原帖
求助DLX模板(关注悬赏)
328170
Kalium楼主2023/3/5 13:58

不知道是不是输入输出格式问题还是代码本身问题

求求了

#include <iostream>
#include <cstdio>
#include <cstring>

const int N = (1 << 12) * (1 << 10) + 7;//行*列

using namespace std;

int T;

char s[20][20];

struct position {
	int row, col;
} pos[N];

struct direction {
	int l, r, u, d;
} dir[N];

int lin[N], sz[N], cnt;

int ans[N];

struct Dancing_Links_X {
	inline void init(int n, int m) {
		for (int i = 0; i <= m; ++ i)
			dir[i] = (direction) {i - 1, i + 1, i, i};
		
		dir[0].l = m, dir[m].r = 0, cnt = m;
	}
	
	inline void insert(int ro, int co) {
		pos[++ cnt] = (position) {ro, co};
		sz[co] ++;
		
		dir[cnt].u = co, dir[cnt].d = dir[co].d;
		dir[dir[co].d].u = cnt, dir[co].d = cnt;
		
		if (lin[ro] == 0) {
			lin[ro] = cnt;
			dir[cnt].l = cnt, dir[cnt].r = cnt;
		} else {
			dir[cnt].l = lin[ro], dir[cnt].r = dir[lin[ro]].r;
			dir[dir[lin[ro]].r].l = cnt, dir[lin[ro]].r = cnt;
		}
	}
	
	inline void remove(int c) {
		dir[dir[c].l].r = dir[c].r;
		dir[dir[c].r].l = dir[c].l;
		
		for (int i = dir[c].d; i != c; i = dir[i].d) {
			for (int j = dir[i].r; j != i; j = dir[j].r) {
				dir[dir[j].d].u = dir[j].u;
				dir[dir[j].u].d = dir[j].d;
				sz[pos[j].col] --;
			}
		}
	}
	
	inline void recover(int c) {
		for (int i = dir[c].u; i != c; i = dir[i].u) {
			for (int j = dir[i].l; j != i; j = dir[j].l) {
				dir[dir[j].d].u = j;
				dir[dir[j].u].d = j;
				sz[pos[j].col] ++;
			}
		}
		
		dir[dir[c].l].r = c;
		dir[dir[c].r].l = c;
	}
} dlx;

void dfs(int step) {
	if (! dir[0].r) {
		for (int i = 1; i < step; ++ i) {
			int r = (ans[i] - 1) / 16 / 16 + 1;
			int c = (ans[i] - 1) / 16 % 16 + 1;
			char tmp = (ans[i] - 1) % 16 + 1 + 'A' - 1;
			
			s[r][c] = tmp;
		}
		
		return ;
	}
	
	int c = dir[0].r;
	
	for (int i = dir[0].r; i; i = dir[i].r)
		if (sz[i] < sz[c]) c = i;
	
	dlx.remove(c);
	
	for (int i = dir[c].d; i != c; i = dir[i].d) {
		ans[step] = pos[i].row;
		
		for (int j = dir[i].r; j != i; j = dir[j].r)
			dlx.remove(pos[j].col);
		
		dfs(step + 1);
		
		for (int j = dir[i].l; j != i; j = dir[j].l)
			dlx.recover(pos[j].col);
	}
	
	dlx.recover(c);
}

int main() {
	int num = 0;
	
	scanf("%d", &T);
	
	while (T --) {
		cnt = 0;
		memset(ans, 0, sizeof(ans));
		memset(dir, 0, sizeof(dir));
		memset(pos, 0, sizeof(pos));
		memset(sz, 0, sizeof(sz));
		memset(lin, 0, sizeof(lin));
		
		dlx.init(1 << 12, 1 << 10);
		
		for (int i = 1; i <= 16; ++ i)
			scanf("%s", s[i] + 1);
		
		if (num) printf("\n");
		
		num ++;
		
		for (int i = 1; i <= 16; ++ i) {
			for (int j = 1; j <= 16; ++ j) {
				for (int k = 1; k <= 16; ++ k) {
					int shu = s[i][j] - 'A' + 1;
					if (s[i][j] == '-') shu = 0;
					
					if (shu && shu != k) continue;
					
					int r = ((i - 1) * 16 + (j - 1)) * 16 + k;
					int c1 = (i - 1) * 16 + (j - 1) + 1;
					int c2 = 256 + (i - 1) * 16 + k;
					int c3 = 256 * 2 + (j - 1) * 16 + k;
					int c4 = 256 * 3 + (((i - 1) / 4) * 4 + ((j - 1) / 4)) * 16 + k;
					
					dlx.insert(r, c1);
					dlx.insert(r, c2);
					dlx.insert(r, c3);
					dlx.insert(r, c4);
				}
			}
		}
		
		dfs(1);
		
		for (int i = 1; i <= 16; ++ i)
			printf("%s\n", s[i] + 1);
	}
	
	return 0;
}
2023/3/5 13:58
加载中...