3076

思路:

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的更多相关文章

  1. (简单) POJ 3076 Sudoku , DLX+精确覆盖。

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  2. POJ 3076 Sudoku DLX精确覆盖

    DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepte ...

  3. POJ 3076 Sudoku (dancing links)

    题目大意: 16*16的数独. 思路分析: 多说无益. 想说的就是dancing links 的行是依照 第一行第一列填 1 第一行第二列填 2 -- 第一行第十五列填15 第一行第二列填 1 -- ...

  4. 搜索(DLX): POJ 3074 3076 Sudoku

    POJ 3074 : Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller ...

  5. 深搜+回溯 POJ 2676 Sudoku

    POJ 2676 Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17627   Accepted: 8538 ...

  6. POJ 3076 / ZOJ 3122 Sudoku(DLX)

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  7. 【POJ 3076】 Sudoku

    [题目链接] http://poj.org/problem?id=3076 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 [代码] #include <algorit ...

  8. 【POJ】3076 Sudoku

    DLX第一题,模板留念. /* 3076 */ #include <iostream> #include <string> #include <map> #incl ...

  9. Sudoku POJ - 3076

    Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 5769   Accepted: 2684 Descripti ...

随机推荐

  1. 【题解】Luogu SP3267 DQUERY - D-query

    原题传送门 这题和Luogu P1972 [SDOI2009]HH的项链很像,只是数据大小有些差别,题解 我博客里对莫队的介绍 我们在排序询问时,普通是这样qaq inline bool cmp(re ...

  2. 神秘的.user.ini文件

    原文链接:https://segmentfault.com/a/1190000011552335

  3. Codeforces 841D Leha and another game about graph - 差分

    Leha plays a computer game, where is on each level is given a connected graph with n vertices and m  ...

  4. Io流的使用

    file的使用 文件流的使用 FileInpunStream  FileOutOputStream   ----------字符流 FileReader Filewriter --------字节流  ...

  5. topcoder srm 663 div1

    problem1 link 每次枚举$S$的两种变化,并判断新的串是否是$T$的子串.不是的话停止搜索. problem2 link 首先考慮增加1个面值为1的硬币后,$ways$数组有什么变化.设原 ...

  6. Window 对象 HTML框架标签(Frame)

    Window 对象 Window 对象表示浏览器中打开的窗口. 如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为每个框架创建一个额外 ...

  7. Python3 tkinter基础 Frame event.x 输出鼠标左右键点击的位置

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. Ubuntu: repository/PPA 源

    在Ubuntu中,每个PPA源是单独存放在/etc/apt/sources.list.d/文件夹中的,进入到该文件夹,使用ls命令查询即可列出当前系统添加的PPA源. 添加 sudo add-apt- ...

  9. 永久修改VS include目录

    原文:https://blog.csdn.net/sysprogram/article/details/49214727 VS2008在选项里可以设置全局的Include目录和Lib目录, 但是VS2 ...

  10. newcoder F石头剪刀布(DFS + 思维)题解

    题意:wzms 今年举办了一场剪刀石头布大赛,bleaves 被选为负责人. 比赛共有 2n 个人参加, 分为 n 轮, 在每轮中,第 1 位选手和第 2 位选手对战,胜者作为新的第 1 位选手, 第 ...