PKU3074 DLX版 数独建01矩阵
来源:互联网 发布:黑客编程入门3pdf 编辑:程序博客网 时间:2024/05/22 15:14
行数为9*9*9 代表9行9列每个格子9种情况,如果当前格子有数则只建一行
列约束为 9*9+9*9+9*9+9*9
分别为行9数,列9数,9*9的格子每个格子一个数,3*3的格子9个每个格子一个数
#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <list>#include <bitset>using namespace std ;#define zero {0}#define INF 0x3f3f3f3f#define EPS 1e-6#define TRUE true#define FALSE falsetypedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){ return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);}#define N 3267//每个1占用一个编码+列数 m+9*9*9*4const int head = 0;int mat[750][350], tor[750], toc[750], dig[750];char str[100];int n, m, size, o[1010], s[750], col[N], row[N], u[N], d[N], l[N], r[N];//将输入条件转化为01矩阵。bool makegragh(){ int strnum, i, j, k, qua, pos, num; scanf("%s", str);//输入 if (strcmp(str, "end") == 0)return false; memset(mat, 0, sizeof(mat));//建图 n = 1; m = 324; strnum = 0;//初始化行列值 for (i = 1; i <= 9; i++) { for (j = 1; j <= 9; j++) { qua = (j - 1) / 3 * 3 + (i - 1) / 3 + 1;// pos = (i - 1) * 9 + j; if (str[strnum] == '.') { for (k = 1; k <= 9; k++) { tor[n] = i; toc[n] = j; dig[n] = k; mat[n][(i - 1) * 9 + k] = 1; mat[n][81 + (j - 1) * 9 + k] = 1; mat[n][162 + (qua - 1) * 9 + k] = 1; mat[n++][243 + pos] = 1; } } else { tor[n] = i; toc[n] = j; num = str[strnum] - '0'; dig[n] = num; mat[n][(i - 1) * 9 + num] = 1; mat[n][81 + (j - 1) * 9 + num] = 1; mat[n][162 + (qua - 1) * 9 + num] = 1; mat[n++][243 + pos] = 1; } strnum++; } } n--; return true;}void Link(int i, int j, int &rowh){ s[j]++; u[size] = u[j]; d[u[j]] = size; u[j] = size; d[size] = j; row[size] = i; col[size] = j; if (rowh == -1) { l[size] = r[size] = size; rowh = size; } else { l[size] = l[rowh]; r[l[rowh]] = size; r[size] = rowh; l[rowh] = size; } size++;}//将01矩阵转化为十字链表,cnt表示结点个数,01矩阵是n行m列的。void initial(){ int i, j, rowh; memset(s, 0, sizeof(s)); for (i = head; i <= m; i++) { r[i] = (i + 1) % (m + 1); l[i] = (i - 1 + m + 1) % (m + 1); u[i] = d[i] = i; } size = m + 1; for (i = 1; i <= n; i++) { rowh = -1; for (j = 1; j <= m; j++) if (mat[i][j]) { Link(i, j, rowh); } } // printf("size=%d\n", size);}//删除矩阵中的列及其相应的行void myremove(const int &cur){ l[r[cur]] = l[cur]; r[l[cur]] = r[cur]; for (int i = d[cur]; i != cur; i = d[i]) { for (int j = r[i]; j != i; j = r[j]) { u[d[j]] = u[j]; d[u[j]] = d[j]; --s[col[j]]; } }}//恢复。顺序和remove相反void myresume(const int &cur){ for (int i = u[cur]; i != cur; i = u[i]) { for (int j = l[i]; j != i; j = l[j]) { ++s[col[j]]; u[d[j]] = j; d[u[j]] = j; } } l[r[cur]] = cur; r[l[cur]] = cur;}//最原始版本,只需输出一组合法解bool dfs(const int &k){ if (r[head] == head) //不需判断k是否等于N { sort(o, o + k); for (int i = 0; i < k; i++) printf("%d", dig[o[i]]); printf("\n"); return true; } int ms = INF, cur = 0; for (int t = r[head]; t != head; t = r[t]) { if (s[t] < ms) { ms = s[t]; cur = t; } } myremove(cur); for (int i = d[cur]; i != cur; i = d[i]) { o[k] = row[i]; for (int j = r[i]; j != i; j = r[j]) myremove(col[j]); if (dfs(k + 1))return true; for (int j = l[i]; j != i; j = l[j]) myresume(col[j]); } myresume(cur); return false;}int main(){#ifdef DeBUGs freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);#endif while (makegragh()) { initial(); dfs(0); } return 0;}
0 0
- PKU3074 DLX版 数独建01矩阵
- DLX
- DLX
- DLX
- 01精确覆盖(DLX类)
- DLX算法解数独游戏 Java版
- DLX PKU3740
- DLX 模板
- DLX(II)
- DLX 学习
- DLX题集
- DLX模板
- hdu1426 DLX
- DLX+hdu2295
- DLX模板
- 模板--DLX
- DLX模板
- DLX专题
- hdu 3746 Cyclic Nacklace
- 获取XML节点完整方法
- Convert array of key value object to object of the key values (ruby)
- 全局探索式测试法
- 字典树模板
- PKU3074 DLX版 数独建01矩阵
- java Excel文件导入导出
- 云计算平台管理的三大利器Nagios、Ganglia和Splunk
- 求最接近的最大2的指数次幂roundup_pow_of_two分析与实现
- Json字符串与Json对象的相互转换
- 数据库的最简单实现
- 把图片画成圆形
- 【LeetCode】Word Break II 解题报告
- linux系统中监控用户的操作记录命令