HDU 3111 Sudoku(精确覆盖)

数独问题,输入谜题,输出解

既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧。。。赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了。。。

  1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 #include <cmath>
6 #include <string>
7 #include <vector>
8 #include <queue>
9 #include <set>
10 using namespace std;
11
12 #define ll long long
13 #define eps 1e-8
14 #define mod 21092013
15
16 #define inf 0x3f3f3f3f
17 #define maxr 777
18 #define maxn (maxr*maxr)
19 int n,m;
20 int L[maxn],R[maxn],U[maxn],D[maxn],cnt;
21 int row[maxn],col[maxn];
22 int N[maxr],use[maxr],head[maxr];
23 void init(){
24 memset(head,-1,sizeof(head));
25 memset(N,0,sizeof(N));
26 for(int i=0;i<=m;++i){
27 L[i]=i-1,R[i]=i+1;
28 U[i]=D[i]=i;
29 row[i]=0,col[i]=i;
30 }
31 L[0]=m,R[m]=0;
32 cnt=m;
33 }
34 void remove(int c){// 删除列以及所在列含有1的行
35 L[R[c]]=L[c],R[L[c]]=R[c];
36 for(int i=D[c];i!=c;i=D[i])
37 for(int j=R[i];j!=i;j=R[j])
38 U[D[j]]=U[j],D[U[j]]=D[j],--N[col[j]];
39 }
40 void resume(int c){// 恢复列以及所在列含有1的行
41 for(int i=U[c];i!=c;i=U[i])
42 for(int j=L[i];j!=i;j=L[j])
43 U[D[j]]=D[U[j]]=j,++N[col[j]];
44 L[R[c]]=R[L[c]]=c;
45 }
46 int low(){
47 int mi=maxr,idx=0;
48 for(int i=R[0];i;i=R[i])if(N[i]<mi&&N[i])mi=N[i],idx=i;
49 return idx;
50 }
51 void link(int r,int c){
52 ++N[c],++cnt;
53 row[cnt]=r,col[cnt]=c;
54 U[cnt]=U[c],D[cnt]=c;
55 U[D[cnt]]=D[U[cnt]]=cnt;
56 if(head[r]==-1)
57 head[r]=L[cnt]=R[cnt]=cnt;
58 else {
59 L[cnt]=L[head[r]];
60 R[cnt]=head[r];
61 L[R[cnt]]=R[L[cnt]]=cnt;
62 }
63 }
64 int xy[maxr][2];char num[maxr];
65 char ch[12][12];
66 bool dance(int dep){
67 if(R[0]==0)return true;
68 int c=low();
69 if(c==0)return false;
70 for(int i=D[c];i!=c;i=D[i]){
71 int r=row[i];
72 ch[xy[r][0]][xy[r][1]]=num[r];
73 use[dep]=i;
74 remove(col[i]);
75 for(int j=R[i];j!=i;j=R[j])remove(col[j]);
76 if(dance(dep+1))return true;
77 for(int j=L[i];j!=i;j=L[j])resume(col[j]);
78 resume(col[i]);
79 }
80 return false;
81 }
82
83 int main(){
84 int t,ca=0;
85 scanf("%d",&t);
86 while(t--){
87 if(ca)scanf("%s",ch[0]);
88 if(ca)puts("---");
89 ca=1;
90 n=0,m=324;
91 init();
92 for(int i=1;i<=9;++i)scanf("%s",ch[i]+1);
93 for(int i=1;i<=9;++i){
94 for(int j=1;j<=9;++j){
95 if(ch[i][j]>=‘0‘&&ch[i][j]<=‘9‘){
96 int val=ch[i][j]-‘0‘;
97 ++n;
98 link(n,(i-1)*9+val);
99 link(n,81+(j-1)*9+val);
100 link(n,162+(i-1)*9+j);
101 link(n,243+((i-1)/3*3+(j+2)/3-1)*9+val );
102 xy[n][0]=i,xy[n][1]=j;
103 num[n]=val+‘0‘;
104 }
105 else {
106 for(int k=1;k<=9;++k){
107 int val=k;
108 ++n;
109 link(n,(i-1)*9+val);
110 link(n,81+(j-1)*9+val);
111 link(n,162+(i-1)*9+j);
112 link(n,243+((i-1)/3*3+(j+2)/3-1)*9+val );
113 xy[n][0]=i,xy[n][1]=j;
114 num[n]=val+‘0‘;
115 }
116 }
117 }
118 }
119 if(dance(0))for(int i=1;i<=9;++i)printf("%s\n",ch[i]+1);
120 else puts("impossible");
121 }
122 return 0;
123 }

HDU 3111 Sudoku(精确覆盖),布布扣,bubuko.com

时间: 2024-12-07 13:27:12

HDU 3111 Sudoku(精确覆盖)的相关文章

hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )

利用 Dancing Link 来解数独 具体的可以看    lrj 的训练指南 和 < Dancing Links 在搜索中的应用 >这篇论文 Dancing Link 来求解数独 , 是通过求解精确覆盖 精确覆盖就是给出一个 01 矩阵 , 要求我们选择一些行 , 使得每一列有且仅有一个 1 对于数独问题 , 行就是我们的选择 , 即在第 i 行 第 j 列 放上 数字 k , 所以我们最多有 i * j * k 中选择 如果某些位置( x , y  )已经放了数字 a , 那么我们的选择

POJ 3047 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

POJ 3076 Sudoku DLX精确覆盖

DLX精确覆盖模版题..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepted: 2143 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 fi

POJ 3074 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

(简单) POJ 3074 Sudoku, DLX+精确覆盖。

Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . . . 6 7 3 5 . . . . . . . 2 9 3 . 5 6 9 2 . 8 . . . . . . . . . . . 6 . 1 7 4 5 . 3 6 4 . . . . . . . 9 5 1

[DLX精确覆盖+打表] hdu 2518 Dominoes

题意: 就是给12种图形,旋转,翻折.有多少种方法构成n*m=60的矩形 思路: 裸的精确覆盖.就是建图麻烦 个人太挫,直接手写每一个图形的各种形态 须要注意的是最后的答案须要除以4 代码: #include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #include"queue" #include"map

[DLX精确覆盖] hdu 3663 Power Stations

题意: 给你n.m.d,代表有n个城市,m条城市之间的关系,每个城市要在日后d天内都有电. 对于每个城市,都有一个发电站,每个发电站可以在[a,b]的每一个连续子区间内发电. x城市发电了,他相邻的城市也有电,并且每个发电站只能启动一次,或者不启动. 现在问,如何安排发电站的启动,保证每个城市d天都有电. 输出发电方案,不发电的话输出0 0 思路: 一个简单的精确覆盖问题,就是建图比较麻烦一点. 这里考虑到每天都要得到电,所以把每个城市每天都设为列(n*d) 然后每个城市对于[a,b]的所有子区

HDU 3957 Street Fighter(搜索、DLX、重复覆盖+精确覆盖)

很久以前就看到的一个经典题,一直没做,今天拿来练手.街霸 给n<=25个角色,每个角色有 1 or 2 个版本(可以理解为普通版以及爆发版),每个角色版本可以KO掉若干人. 问最少选多少个角色(每个角色只能选一次),使得可以KO掉其他所有人(包括所有版本). 典型的DLX.前∑mode[i]列表示被KO的人版本,重复覆盖.后n列表示选了的人,精确覆盖. 即,在精确覆盖满足的前提下,完成重复覆盖,且使所选行最少. 据说这题可以转化成只用一种覆盖,或者是dfs+剪枝.这里就先这样吧. 加了好多注释,

[DLX精确覆盖] hdu 1603 A Puzzling Problem

题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个位置再加上n个碎片也就是16+n 然后注意下成立的判定就好了 代码: #include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #inc