题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=660

TimeLimit: 3.000 seconds

A Sudoku grid is a 16 x 16 grid of cells grouped in sixteen 4 x 4 squares, where some cells are filled with letters from A to P (the first 16 capital letters of the English alphabet), as shown in figure 1a. The game is to fill all the empty grid cells with letters from A to P such that each letter from the grid occurs once only in the line, the column, and the 4 x 4 square it occupies. The initial content of the grid satisfies the constraints mentioned above and guarantees a unique solution.

Figure 1. Sudoku
    A         C           O   I
  J     A   B   P   C G F   H  
    D     F   I   E         P  
  G   E L   H         M   J    
        E         C     G      
  I     K   G A   B       E   J
D   G P     J   F         A    
  E       C   B     D P     O  
E     F   M     D     L   K   A
  C                 O   I   L  
H   P   C     F   A     B      
      G   O D       J         H
K       J         H   A   P   L
    B     P     E     K     A  
  H     B     K     F I   C    
    F       C     D     H   N  
                               
a) Sudoku grid
F P A H M J E C N L B D K O G I
O J M I A N B D P K C G F L H E
L N D K G F O I J E A H M B P C
B G C E L K H P O F I M A J D N
M F H B E L P O A C K J G N I D
C I L N K D G A H B M O P E F J
D O G P I H J M F N L E C A K B
J E K A F C N B G I D P L H O M
E B O F P M I J D G H L N K C A
N C J D H B A E K M O F I G L P
H M P L C G K F I A E N B D J O
A K I G N O D L B P J C E F M H
K D E M J I F N C H G A O P B L
G L B C D P M H E O N K J I A F
P H N O B A L K M J F I D C E G
I A F J O E C G L D P B H M N K
                               
b) Solution

Write a Sudoku playing program that reads data sets from a text file.

Input

Each data set encodes a grid and contains 16 strings on 16 consecutive lines as shown in figure 2. The i-th string stands for the i-th line of the grid, is 16 characters long, and starts from the first position of the line. String characters are from the set {A,B,...,P,-}, where `-' (minus) designates empty grid cells. The data sets are separated by single empty lines and terminate with an end of file.

Output

The program prints the solution of the input encoded grids in the same format and order as used for input.

Sample Input

--A----C-----O-I
-J--A-B-P-CGF-H-
--D--F-I-E----P-
-G-EL-H----M-J--
----E----C--G---
-I--K-GA-B---E-J
D-GP--J-F----A--
-E---C-B--DP--O-
E--F-M--D--L-K-A
-C--------O-I-L-
H-P-C--F-A--B---
---G-OD---J----H
K---J----H-A-P-L
--B--P--E--K--A-
-H--B--K--FI-C--
--F---C--D--H-N-

Sample Output

FPAHMJECNLBDKOGI
OJMIANBDPKCGFLHE
LNDKGFOIJEAHMBPC
BGCELKHPOFIMAJDN
MFHBELPOACKJGNID
CILNKDGAHBMOPEFJ
DOGPIHJMFNLECAKB
JEKAFCNBGIDPLHOM
EBOFPMIJDGHLNKCA
NCJDHBAEKMOFIGLP
HMPLCGKFIAENBDJO
AKIGNODLBPJCEFMH
KDEMJIFNCHGAOPBL
GLBCDPMHEONKJIAF
PHNOBALKMJFIDCEG
IAFJOECGLDPBHMNK

题意:求解16行16列数独问题的一组解:给定一个16*16的字母方阵,要求将所有的空格子填上A~P中的一个字符,并满足以下条件。

1.每行A~P恰好各出现一次

2.每列A~P恰好各出现一次

3.粗线分隔出的每个4*4子方阵(一共有4*4个)中,A~P恰好各出现一次。

分析:直接套DLX

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;const int maxn = 1024 + 10;
const int maxr = 4096 + 10;
const int maxnode = maxr * 4 + maxn;// 行编号从1开始,列编号为1~n,结点0是表头结点,节点1~n是各列顶部的虚拟结点
struct DLX {int n, sz; // 列数,结点总数int S[maxn]; // 各列结点数int row[maxnode], col[maxnode]; // 各结点行列编号int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; // 十字链表int ansd, ans[maxr]; // 解void init(int n) { // n是列数this->n = n;// 虚拟结点for(int i = 0; i <= n; i++) {U[i] = i; D[i] = i; L[i] = i - 1; R[i] = i + 1;}R[n] = 0; L[0] = n;sz = n + 1;memset(S, 0, sizeof(S));}void addRow(int r, vector<int> columns) {int first = sz;for(int i = 0; i < columns.size(); i++) {int c = columns[i];L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];D[U[c]] = sz; U[c] = sz;row[sz] = r; col[sz] = c;S[c]++; sz++;}R[sz-1] = first; L[first] = sz - 1;}// 顺着链表,遍历除s外的其他元素  #define FOR(i, A, s) for(int i = A[s]; i != s; i = A[i])void remove(int c) {L[R[c]] = L[c];R[L[c]] = R[c];for(int i = D[c]; i != c; 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]];}}void restore(int c) {for(int i = U[c]; i != c; 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[c]] = c;R[L[c]] = c;}// d为递归深度bool dfs(int d) {if(R[0] == 0) { // 找到解ansd = d; // 记录解的长度return true;}int c = R[0]; //第一个未删除的列for(int i = R[0]; i != 0; i = R[i])if(S[i] < S[c]) c = i;remove(c); // 删除第c列for(int i = D[c]; i != c; i = D[i]) { // 用结点i所在行覆盖第c列ans[d] = row[i];for(int j = R[i]; j != i; j = R[j]) remove(col[j]); // 删除结点i所在行能覆盖的所有其他列if(dfs(d + 1)) return true;for(int j = L[i]; j != i; j = L[j]) restore(col[j]); // 恢复结点i所在行能覆盖的所有其他列}restore(c); // 恢复第c列return false;}bool solve(vector<int> &v) {v.clear();if(!dfs(0)) return false;for(int i = 0; i < ansd; i++) v.push_back(ans[i]);return true;}
};DLX solver;const int SLOT = 0;
const int ROW = 1;
const int COL = 2;
const int SUB = 3;// 行/列的统一编解码函数,从1开始编号
inline int encode(int a, int b, int c) {return a * 256 + b * 16 + c + 1;
}void decode(int code, int &a, int &b, int &c) {code--;c = code % 16; code /= 16;b = code % 16; code /= 16;a = code;
}char  puzzle[16][20];bool read() {for(int i = 0; i < 16; i++)if(scanf("%s", puzzle[i]) == EOF) return false;return true;
}int main()
{int kase = 0;while(read()) {if(++kase != 1) printf("\n");solver.init(1024);for(int r = 0; r < 16; r++)for(int c = 0; c < 16; c++)for(int v = 0; v < 16; v++)if(puzzle[r][c] == '-' || puzzle[r][c] == 'A' + v) {vector<int> columns;columns.push_back(encode(SLOT, r, c));columns.push_back(encode(ROW, r, v));columns.push_back(encode(COL, c, v));columns.push_back(encode(SUB, (r/4)*4+c/4, v));solver.addRow(encode(r, c, v), columns);}vector<int> ans;solver.solve(ans);for(int i = 0; i < ans.size(); i++) {int r, c, v;decode(ans[i], r, c, v);puzzle[r][c] = 'A' + v;}for(int i = 0; i < 16; i++)printf("%s\n", puzzle[i]);}return 0;
}

LA 2659 poj 3076 zoj 3122 Sudoku(精确覆盖 + DLX)相关推荐

  1. HDOJ 4069 Squiggly Sudoku 精确覆盖+搜索

    //HDOJ 4069 Squiggly Sudoku 精确覆盖+搜索 /* 题意:数独变形 9块弯弯曲曲的区域 每块有9个小格往这81个格子里面填写1-9的数字,使得每行,每列,每个区域都含有1.2 ...

  2. UVA 413|LA 5388|POJ 1492|ZOJ 1338 Up and Down Sequences

    https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364837 题意:如果是上升序列,上升序列的长度不是所有上升数字的,是这么规 ...

  3. 精确覆盖DLX算法模板

    代码 struct DLX {int n,id;int L[maxn],R[maxn],U[maxn],D[maxn];int C[maxn],S[maxn],loc[maxn][2];void in ...

  4. DLX精确覆盖 hdu4069 Squiggly Sudoku

    传送门:点击打开链接 题意:将9*9的棋盘分割成了9个部分,每个部分都是9个格子,然后现在要求每个部分的数字恰是1~9的排列,每一行每一列恰是1~9的排列,问是否有解,有多少组解,如果只有1组解打印出 ...

  5. HDU 4069 Squiggly Sudoku【Dancing Links精确覆盖】

    跟普通的数独有一点点不同,先预处理一下再用Dancing Links进行精确覆盖即可. #include <iostream> #include <cstdio> #inclu ...

  6. DLX (Dancing Links/舞蹈链)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  7. CTF PWN之精确覆盖变量数据

    刚开始接触pwn的朋友在做pwn练习时可能会有这样的疑问,怎么做到精确覆盖变量数据呢? 我们做pwn练习之前需要先知道:命令行参数C语言的main函数拥有两个参数,为int类型的argc参数,以及ch ...

  8. CTF-PWN练习之精确覆盖变量数据

    目录 预备知识 一.相关实验 二.命令行参数 三.xargs命令 四.字节序 实验目的 实验环境 实验步骤一 源码审计 实验步骤二 使用gdb调试程序 实验步骤三 发起溢出攻击 预备知识 本实验要求实 ...

  9. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

最新文章

  1. DDD+中台+微服务,yyds
  2. 重构-改善既有代码的设计 读书笔记
  3. syslog记录history历史记录
  4. 蓝桥杯-2的次幂表示(java)
  5. C# 中特性(Attribute)的使用简介
  6. Elasticsearch、Elasticsearch-head、Kibana 安全设置账号密码验证登陆
  7. 通信协议—HTTP、TCP、UDP
  8. 关于Cohen-Sutherland算法和Liang-Barsky算法
  9. Android UI事件传递就是这么个事儿
  10. AcWing 1843. 圆形牛棚(暴力+枚举)
  11. POJ2536 Gopher II【二分图最大匹配】
  12. linux查看内存占用情况
  13. “熊猫烧香”有新变种 可自动下载病毒
  14. cmd 文本文件分割_cmd - 分割大文件
  15. 计算机需要那些高中数学知识点,高中必考数学知识点归纳整理
  16. 手机浏览器下载IOS版APP
  17. 【机器学习】阿里云天池竞赛——工业蒸汽量预测(6)
  18. ijkplayer源码---FFPlayer结构体3 SDL_Vout
  19. 永劫无间组装电脑配置推荐2021 玩永劫无间需要什么配置
  20. phpcms富文本框上传图片去除水印

热门文章

  1. 富交互Web应用中的撤销和前进
  2. 何时使用[self release]
  3. 自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  4. iOS开发UI篇—iOS开发中三种简单的动画设置
  5. linux轻量级进程LWP
  6. 使用 Edit + MASM 5.0 编译器 + Linker 连接器
  7. 跨库查询(OpenDataSource)与链接服务器(Linking Server)
  8. 一款非常好用的Linux下的C/C++ IDE
  9. human-robotic eco system
  10. discussion function on the github system