POJ 3076 Sudoku
思路:
dfs + 剪枝
首先,如果这个位置只能填一种字母,那就直接填
其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它
然后,对于某个位置如果不能填字母了,或者某种字母在一行一列或一块中出向了两次以上,说明当前方案不成立
最后贪心地从可选情况少的往下搜
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head const int N = ;
int mp[N][N];
int st[N][N];
int sum = ;
char s[N][N+];
void add(int x, int y, int t) {
mp[x][y] = t;
sum++;
for (int i = ; i <= ; i++) {
st[i][y] |= <<t-;
st[x][i] |= <<t-;
}
int xx = (x+)/, yy = (y+)/;
for (int i = (xx-)* + ; i <= xx*; i++) {
for (int j = (yy-)* + ; j <= yy*; j++) {
st[i][j] |= <<t-;
}
}
}
void print() {
for (int i = ; i <= ; i++) {
for (int j = ; j <= ; j++) {
putchar(mp[i][j]-+'A');
}
puts("");
}
puts("");
}
bool dfs() {
if(sum == ) {
print();
return true;
} for (int i = ; i <= ; i++) {
for (int j = ; j <= ; j++) {
if(!mp[i][j]) {
int cnt = , t = ;
for (int k = ; k <= ; k++) {
if((st[i][j] & (<<k-)) == ) {
cnt++;
t = k;
if(cnt == ) break;
}
}
if(!cnt) return false;
if(cnt == ) add(i, j, t);
}
}
} for (int i = ; i <= ; i++) {
for (int k = ; k <= ; k++) {
int cnt1 = , cnt2 = , y;
for (int j = ; j <= ; j++) {
if(mp[i][j] == k) cnt1++;
if(cnt1 == ) return false;
if(!mp[i][j] && (st[i][j] & (<<k-)) == ) cnt2++, y = j;
}
if(!cnt1 && !cnt2) return false;
if(!cnt1 && cnt2 == ) add(i, y, k);
}
} for (int j = ; j <= ; j++) {
for (int k = ; k <= ; k++) {
int cnt1 = , cnt2 = , x;
for (int i = ; i <= ; i++) {
if(mp[i][j] == k) cnt1++;
if(cnt1 == ) return false;
if(!mp[i][j] && (st[i][j] & (<<k-)) == ) cnt2++, x = i;
}
if(!cnt1 && !cnt2) return false;
if(!cnt1 && cnt2 == ) add(x, j, k);
}
} for (int i = ; i <= ; i++) {
int x = (i+)/, y = i - (x-)*;
for (int k = ; k <= ; k++) {
int cnt1 = , cnt2 = , xx, yy;
for (int ii = (x-)*+; ii <= x*; ii++) {
for (int jj = (y-)*+; jj <= y*; jj++) {
if(mp[ii][jj] == k) cnt1++;
if(cnt1 == ) return false;
if(!mp[ii][jj] && (st[ii][jj] & (<<k-)) == ) cnt2++, xx = ii, yy = jj;
}
}
if(!cnt1 && !cnt2) return false;
if(!cnt1 && cnt2 == ) add(xx, yy, k);
}
}
if(sum == ) {
print();
return true;
} int mn = N, x, y;
for (int i = ; i <= ; i++) {
for (int j = ; j <= ; j++) {
if(!mp[i][j]) {
int cnt = ;
for (int k = ; k <= ; k++) {
if((st[i][j] & (<<k-)) == ) {
cnt++;
if(cnt >= mn) break;
}
}
if(cnt < mn) {
mn = cnt;
x = i;
y = j;
}
}
}
}
int tst[N][N], tmp[N][N];
memcpy(tst, st, sizeof(st));
memcpy(tmp, mp, sizeof(mp));
int tsum = sum; for (int k = ; k <= ; k++) {
if((st[x][y] & (<<k-)) == ) {
add(x, y, k);
bool f = dfs();
if(!f) {
memcpy(st, tst, sizeof(tst));
memcpy(mp, tmp, sizeof(tmp));
sum = tsum;
}
else return true;
}
}
return false;
}
int main() {
while(scanf("%s", s[]+) != EOF){
for (int i = ; i <= ; i++) {
scanf("%s", s[i]+);
}
sum = ;
mem(mp, );
mem(st, );
for (int i = ; i <= ; i++) {
for (int j = ; j <= ; j++) {
if(isalpha(s[i][j])) add(i, j, s[i][j] - 'A' + );
}
}
dfs();
}
return ;
}
/*
--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-
*/
POJ 3076 Sudoku的更多相关文章
- (简单) POJ 3076 Sudoku , DLX+精确覆盖。
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- POJ 3076 Sudoku DLX精确覆盖
DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 4416 Accepte ...
- POJ 3076 Sudoku (dancing links)
题目大意: 16*16的数独. 思路分析: 多说无益. 想说的就是dancing links 的行是依照 第一行第一列填 1 第一行第二列填 2 -- 第一行第十五列填15 第一行第二列填 1 -- ...
- 搜索(DLX): POJ 3074 3076 Sudoku
POJ 3074 : Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller ...
- 深搜+回溯 POJ 2676 Sudoku
POJ 2676 Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17627 Accepted: 8538 ...
- POJ 3076 / ZOJ 3122 Sudoku(DLX)
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- 【POJ 3076】 Sudoku
[题目链接] http://poj.org/problem?id=3076 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 [代码] #include <algorit ...
- 【POJ】3076 Sudoku
DLX第一题,模板留念. /* 3076 */ #include <iostream> #include <string> #include <map> #incl ...
- Sudoku POJ - 3076
Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 5769 Accepted: 2684 Descripti ...
随机推荐
- JVM的垃圾回收机制
JVM的垃圾回收机制:(GC通过确定对象是否被活动对象引用来确定是否收集该对象.) 1.触发GC(Garbage Collector)的条件. (1.GC在优先级最低的线程中运行,在未运行的线程中进行 ...
- Excel vba map/dictionary
今天在调整一生成java代码的工具时,要用到在不同语言间互转数据类型的逻辑,原来的代码中根据excel记录的行号来计算,再到另外一个collection中获取,个人想着这也太土鳖了,于是搜了下,在vb ...
- mysql主从(主备)同步一键配置,配自动检测功能
主从一键shell配置 做个笔记. #!/bin/bash #Mysql sync #chenglee #master机器ip MasterIP="192.168.137.174" ...
- sentos7为例添加python3和python2共存
转载:https://www.cnblogs.com/JahanGu/p/7452527.html 1.查看是否已经安装Python CentOS 7.2 默认安装了python2.7.5 因为一些命 ...
- 缩点:Power Plant;
题目传送门:[UVALive 6437]Power Plant 题目大意:T组数据,给定一幅带权图(n, m), 然后给定k个点, 与图中存在有若干条边.每个点都要至少要和这k个点的一个点直接或间接相 ...
- day 27 异常处理
一.异常 1.什么是异常? 异常指的是与正常情况不同在程序中 程序的正常执行过程 按照代码顺序 一行一行的执行 直到所有的代码都执行完如果在执行过程中出现了错误导致代码无法执行完毕 这就称之为异常异常 ...
- (转)Spring Cloud(二)
(二期)23.微服务框架spring cloud(二) [课程23]熔断器-Hystrix.xmind0.1MB [课程23]微服务...zuul.xmind0.2MB 熔断器-Hystrix 雪崩效 ...
- Python入门 值内存管理与所有的关键字
值内存管理 Python采用的是基于值得内存管理方式,如果为不同变量赋值为相同值,这个值在内存中只有一份,多个变量指向同一块内存地址. id(x) : 用于返回变量所指值的内存地址 x = 3 pri ...
- 快速理解Java中的七种单例模式
饿汉式(推荐) package concurencyv2.chapter1; public class SingletonV2 { private static final SingletonV2 i ...
- C++笔记(2018/2/7)
类class 类的名字就是用户自定义的类型的名字.可以像使用基本类型那样来使用它. 一个类所占用的内存空间的大小,等于所有成员变量的大小之和. 类之间可以用 "="进行赋值,但是不 ...