Description

A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 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 4x4 square it occupies. The initial content of the grid satisfies the constraints mentioned above and guarantees a unique 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.

题目大意:填一个16×16的数独。

思路:套DLX。

代码(POJ 641MS / ZOJ 390MS)

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAXC = + ;
const int MAXR = + ;
const int MAXP = MAXR * + MAXC; struct DLX {
int n, sz;//列数,结点总数
int sum[MAXC];//每列拥有的结点数
int row[MAXP], col[MAXP];//结点所在的行和列
int left[MAXP], right[MAXP], up[MAXP], down[MAXP];//十字链表
int ansd, ans[MAXR]; void init(int nn) {
n = nn;
for(int i = ; i <= n; ++i) {
up[i] = down[i] = i;
left[i] = i - ; right[i] = i + ;
}
right[n] = ; left[] = n;
sz = n + ;
memset(sum, , sizeof(sum));
} void add_row(int r, vector<int> columns) {
int first = sz;
for(int i = , len = columns.size(); i < len; ++i) {
int c = columns[i];
left[sz] = sz - ; right[sz] = sz + ; down[sz] = c; up[sz] = up[c];
down[up[c]] = sz; up[c] = sz;
row[sz] = r; col[sz] = c;
++sum[c]; ++sz;
}
right[sz - ] = first; left[first] = sz - ;
} void remove(int c) {
left[right[c]] = left[c];
right[left[c]] = right[c];
for(int i = down[c]; i != c; i = down[i])
for(int j = right[i]; j != i; j = right[j]) {
up[down[j]] = up[j]; down[up[j]] = down[j]; --sum[col[j]];
}
} void restore(int c) {
for(int i = up[c]; i != c; i = up[i])
for(int j = left[i]; j != i; j = left[j]) {
up[down[j]] = j; down[up[j]] = j; ++sum[col[j]];
}
left[right[c]] = c;
right[left[c]] = c;
} bool dfs(int d) {
if(right[] == ) {
ansd = d;
return true;
}
int c = right[];
for(int i = right[]; i != ; i = right[i]) if(sum[i] < sum[c]) c = i;
remove(c);
for(int i = down[c]; i != c; i = down[i]) {
ans[d] = row[i];
for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
if(dfs(d + )) return true;
for(int j = left[i]; j != i; j = left[j]) restore(col[j]);
}
restore(c);
return false;
} bool solve(vector<int> &v) {
v.clear();
if(!dfs()) return false;
for(int i = ; i < ansd; ++i) v.push_back(ans[i]);
return true;
}
}; DLX solver; const int SLOT = ;
const int ROW = ;
const int COL = ;
const int SUB = ; inline int encode(int a, int b, int c) {
return a * + b * + c + ;
} void decode(int code, int &a, int &b, int &c) {
--code;
c = code % ; code /= ;
b = code % ; code /= ;
a = code;
} char puzzle[][]; bool read() {
for(int i = ; i < ; ++i)
if(scanf("%s", puzzle[i]) == EOF) return false;
return true;
} int main() {
int kase = ;
while(read()) {
if(++kase != ) printf("\n");
solver.init();
for(int r = ; r < ; ++r)
for(int c = ; c < ; ++c)
for(int v = ; v < ; ++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/)*+c/, v));
solver.add_row(encode(r, c, v), columns);
}
vector<int> ans;
solver.solve(ans);
for(int i = , len = ans.size(); i < len; ++i) {
int r, c, v;
decode(ans[i], r, c, v);
puzzle[r][c] = 'A' + v;
}
for(int i = ; i < ; ++i) printf("%s\n", puzzle[i]);
}
}

POJ 3076 / ZOJ 3122 Sudoku(DLX)的更多相关文章

  1. HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...

  2. 【UVA1309】Sudoku(DLX)

    点此看题面 大致题意: 让你填完整一个\(16*16\)的数独. 解题思路 我们知道,数独问题显然可以用\(DLX\)解决. 考虑对于一个数独,它要满足的要求为:每个位置都必须有数,每一行都必须有全部 ...

  3. POJ 1979 Red and Black (红与黑)

    POJ 1979 Red and Black (红与黑) Time Limit: 1000MS    Memory Limit: 30000K Description 题目描述 There is a ...

  4. 舞蹈链(DLX)

    舞蹈链(DLX) Tags:搜索 作业部落 评论地址 一.概述 特别特别感谢这位童鞋His blog 舞蹈链是一种优美的搜索,就像下面这样跳舞- 舞蹈链用于解决精确覆盖或者重复覆盖的问题 你可以想象成 ...

  5. POJ 3268 Silver Cow Party (最短路径)

    POJ 3268 Silver Cow Party (最短路径) Description One cow from each of N farms (1 ≤ N ≤ 1000) convenientl ...

  6. POJ.3087 Shuffle'm Up (模拟)

    POJ.3087 Shuffle'm Up (模拟) 题意分析 给定两个长度为len的字符串s1和s2, 接着给出一个长度为len*2的字符串s12. 将字符串s1和s2通过一定的变换变成s12,找到 ...

  7. POJ.1426 Find The Multiple (BFS)

    POJ.1426 Find The Multiple (BFS) 题意分析 给出一个数字n,求出一个由01组成的十进制数,并且是n的倍数. 思路就是从1开始,枚举下一位,因为下一位只能是0或1,故这个 ...

  8. POJ 2676 Sudoku (DFS)

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11694   Accepted: 5812   Special ...

  9. zoj 2358,poj 1775 Sum of Factorials(数学题)

    题目poj 题目zoj //我感觉是题目表述不确切,比如他没规定xi能不能重复,比如都用1,那么除了0,都是YES了 //算了,这种题目,百度来的过程,多看看记住就好 //题目意思:判断一个非负整数n ...

随机推荐

  1. js标准对象

    在JavaScript的世界里,一切都是对象. 但是某些对象还是和其他对象不太一样.为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是返回一个字符串: typeof 123; //'n ...

  2. 重写equals方法(未完)

    equals方法是我们日常编程中很常见的方法,Object中对这个方法的解释如下: boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”. 查看该方法的底层代码如 ...

  3. JVM由浅入深

    运行时数据区域 Java比起C++一个很大的进步就在于Java不用再手动控制指针的delete与free,统一交由JVM管理,但也正因为如此,一旦出现内存溢出异常,不了解JVM,那么排查问题将会变成一 ...

  4. Oracle中with关键字的使用

    open p_cr1 for with sqla as (select d.*, (select c.STATICMONTH from ly_zg_jzfbtstatic c where c.ID = ...

  5. Redis高可用复制集群实现

    redis简单介绍 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库.Redis 与其他 key - value 缓存产品有以下三个特点: 支持数据的持久化,可以将 ...

  6. 关于python的GIL

    转自依云在知乎上的回答,链接为https://www.zhihu.com/question/27245271/answer/462975593 侵删. python的多线程,其实不是真的多线程,它会通 ...

  7. vue 中父子组件之间的交互

    1,最直接的也是最简单的方法是利用props来数据传值. 子组件定义如下: props: { iconClass: { type: String, required: true }, classNam ...

  8. ctf题目writeup(7)

    2019.2.10 过年休息归来,继续做题. bugku的web题,地址:https://ctf.bugku.com/challenges 1. http://123.206.87.240:8002/ ...

  9. ADB工具的安装

    1.Windows ADB工具下载地址: https://developer.android.google.cn/studio/releases/platform-tools ADB工具官网教程: h ...

  10. R语言学习笔记(九):fivenum()与quantile()

    fivenum() fivenum(x, na.rm = TRUE) x 为数值型向量,可以包含NA以及Inf,-Inf na.rm = TRUE 默认将NA和NaN去除,但是Inf还保留. five ...