poj3074Sudoku(DLX解9*9数独)
来源:互联网 发布:h5支付域名 编辑:程序博客网 时间:2024/05/12 16:29
->题目请戳这里<-
题目大意:填9*9数独,就不多废话了。
题目分析:以前写数独是用搜索做的,略带暴力枚举,代码量比较大,效率也不高,最近学dancing links,用来解决精确覆盖问题,效率蛮高,而且代码非常优雅。关于数独转化成精确覆盖问题,这篇论文讲的很详细,就不在这里班门弄斧了,详情请见代码:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 9 * 9 * 9 * 9 * 9 * 4 + 5;//9 * 9 * 9行9 * 9 * 4列int s[N],h[N],u[N],d[N],l[N],r[N],col[N],row[N],ans[N];int head,num;char str[200];void init(){ memset(s,0,sizeof(s));//记得初始化,否则TLE!! head = 0; int i; int c = 9 * 9 * 4; for(i = 0;i <= c;i ++) { u[i] = d[i] = i; l[i] = (i - 1 + c + 1) % (c + 1); r[i] = (i + 1) % (c + 1); } num = c + 1; memset(h,0,sizeof(h));}void insert(int i,int j){ if(h[i]) { r[num] = h[i]; l[num] = l[h[i]]; l[r[num]] = num; r[l[num]] = num; } else { h[i] = num; l[num] = r[num] = num; } s[j] ++; u[num] = u[j]; d[num] = j; d[u[j]] = num; u[j] = num; col[num] = j; row[num] = i; num ++;}void del(int c){ l[r[c]] = l[c]; r[l[c]] = r[c]; int i,j; for(i = d[c];i != c;i = d[i]) { for(j = r[i];j != i;j = r[j]) { u[d[j]] = u[j]; d[u[j]] = d[j]; s[col[j]] --; } }}void recover(int c){ int i,j; for(i = u[c];i != c;i = u[i]) { for(j = l[i];j != i;j = l[j]) { s[col[j]] ++; u[d[j]] = d[u[j]] = j; } } r[l[c]] = l[r[c]] = c;}bool dfs(int k){ int i,j; if(r[head] == head) { sort(ans,ans + 81); for(i = 0;i < 81;i ++) { printf("%d",ans[i] - i * 9); } printf("\n"); return true; } int mn = N; int c; for(i = r[head];i != head;i = r[i]) { if(s[i] < mn) { mn = s[i]; c = i; } } del(c); for(i = d[c];i != c;i = d[i]) { ans[k] = row[i]; for(j = r[i];j != i;j = r[j]) del(col[j]); if(dfs(k + 1)) return true; for(j = l[i];j != i;j = l[j]) recover(col[j]); } recover(c); return false;}int main(){ while(scanf("%s",str) != EOF) { if(str[0] == 'e') break; init(); //system("pause"); for(int i = 0;i < strlen(str);i ++) { int rr = i / 9; int cc = i - rr * 9; int base = (rr * 9 + cc) * 9; if(str[i] == '.') { for(int k = 1;k <= 9;k ++)//依次填充1-9 { insert(base + k,rr * 9 + k);//第rr行填k insert(base + k,81 + 9 * cc + k);//第cc列填k insert(base + k,81 + 81 + (3 * (rr / 3) + cc / 3) * 9 + k); insert(base + k,81 + 81 + 81 + rr * 9 + cc + 1); } } else { insert(base + str[i] - '0',rr * 9 + str[i] - '0'); insert(base + str[i] - '0',81 + 9 * cc + str[i] - '0'); insert(base + str[i] - '0',81 + 81 + (3 * (rr / 3) + cc / 3) * 9 + str[i] - '0'); insert(base + str[i] - '0',81 + 81 + 81 + rr * 9 + cc + 1); } } dfs(0); } return 0;}//7568K375MS
- poj3074Sudoku(DLX解9*9数独)
- poj3074 9*9数独,poj3076 16*16数独 DLX
- DLX解9*9数独 数组模拟双向十字链表
- DLX解 各种规模数独
- poj3074,3076 数独!(DLX)
- POJ 3076 数独DLX
- DLX(变形数独)hdu4069
- uva 1309 数独【DLX】
- POJ 3074 Sudoku (DLX解经典数独)
- DLX之数独问题的解决
- poj 2676 dfs/DLX(数独)
- POJ 2676 数独 Dancing-Links(DLX)
- 【位运算DFS/DLX】【HDU1426】【数独】
- 【搜索】DLX解靶形数独
- HDU 4069 Squiggly Sudoku 数独DLX 福州网络赛
- DLX算法及应用(三)杀手数独
- ACM练级日志:POJ 3074 数独与DLX
- POJ 3074 DLX精确覆盖求解数独问题
- [C#网络编程系列]专题一:网络协议简介
- Java中的字符串翻转
- ruby实现按键精灵的功能
- 【转】和我一起来学iOS(五)负责表现的CALayer
- 遥控三通直升机飞行原理简介
- poj3074Sudoku(DLX解9*9数独)
- JDBC学习
- 制作ramdisk
- java 除0
- 数的非递归前序遍历
- EXTENDING COCOS2D CCSPRITE TO HANDLE TOUCHES
- 管理小故事8
- 利用shell按创建时间批量重命名照片
- 315,关于《C程序设计伴侣》一书致人民邮电出版社的公开信