POJ2676,HDU4069解决数独的两种实现:DFS、DLX

搜索实现:解决数独有两种思考策略,一种是枚举当前格能填的数字的种数,这里有一优化策略就是先搜索能填入种数小的格子;另一种是考虑处理某一行(列、宫)时,对于某一个没用过的数字,若该行(列、宫)只有一个可行的空白格时,就只能将该数字填入此格中。第二种实现起来略麻烦,此处仅实现第一种策略,并调整搜索顺序进行优化操作,优先搜索能填数字种数较小的格子。

另外,在搜索时,条件判断的效率尤为重要,故分别记录各行、各列、各宫已经出现的数字,这样就可以直接判断该空格填入某数字是否可行。

以POJ2676为例,无调整搜索顺序的优化,用时26ms,调整搜索顺序后用时0ms。

 1 //dfs搜索,枚举当前格能填的数字
 2 #include <stdio.h>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 9;
 6 char mp[N+1][N+1];
 7 int row[N+1], col[N+1], squ[N+1];
 8 struct p{
 9     int x, y, z;
10     p(int a = 0, int b = 0, int c = 0) :x(a), y(b), z(c){}
11     bool operator <(const p& m)const {
12         return z < m.z;
13     }
14 };
15 p pa[N*N+1];
16 int tot;
17 
18 bool dfs(int d) {
19     if (d == tot) return true;
20 
21     for(int i = d; i < tot; i++){
22         int nn = 0, x = pa[i].x, y = pa[i].y;
23         pa[i].z = 0;
24         for(int j = 1; j < 512; j <<= 1)
25             if( !(row[x]&j) && !(col[y]&j) && !(squ[x/3*3+y/3]&j) )
26                 pa[i].z++;
27     }
28     sort(pa+d, pa+tot);//调整搜素顺序!!
29 
30     int x = pa[d].x, y = pa[d].y;
31     for(int i = 1; i <= N; i++){
32         int j = 1 <<(i-1);
33         if(!(row[x]&j) && !(col[y]&j) && !(squ[x/3*3+y/3]&j)){
34             row[x] ^= j, col[y] ^= j, squ[x/3*3+y/3] ^= j;
35             mp[x][y] = '0'+i;
36             if(dfs(d+1)) return true;
37             row[x] ^= j, col[y] ^= j, squ[x/3*3+y/3] ^= j;
38         }
39     }
40     return false;
41 }
42 
43 int main(){
44     int t; scanf("%d", &t);
45     while(t--){
46         for(int i = 0; i < 9; i++)
47             for(int j = 0; j < 9; j++)
48                 scanf(" %c", &mp[i][j]);
49 
50         for(int i = 0; i < N; i++)
51             row[i] = col[i] = squ[i] = 0;
52         tot = 0;
53 
54         for(int i = 0; i < N; i++)
55             for(int j = 0; j < N; j++)
56                 if(mp[i][j] != '0'){
57                     int idx = mp[i][j]-'1';
58                     row[i] |= 1<<idx, col[j] |= 1<<idx, squ[i/3*3+j/3] |= 1<<idx;
59                 }
60                 else
61                     pa[tot++] = p(i, j);
62 
63         for(int i = 0; i < tot; i++){
64             int nn = 0, x = pa[i].x, y = pa[i].y;
65             for(int j = 1; j < 512; j <<= 1)
66                 if( !(row[x]&j) && !(col[y]&j) && !(squ[x/3*3+y/3]&j) )
67                     pa[i].z++;
68         }
69 
70         dfs(0);
71 
72         for (int i = 0; i < 9; ++i)
73             puts(mp[i]);
74     }
75     return 0;
76 }
View Code

 

DLX算法的POJ2676

  1 //******************************************************//
  2 //输入T表示T组数据。                                    //
  3 //每组数据为9个长度为9的字符串,空白处以字符0替代。        //
  4 //POJ2676                                               //
  5 //******************************************************//
  6 
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 const int maxnode = 100010;
 10 const int MaxM = 1010;
 11 const int MaxN = 1010;
 12 struct DLX{
 13     int n, m, size;                 //行数,列数,总数
 14     int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
 15     int H[MaxN], S[MaxM];           //S记录该列剩余1的个数,H表示该行最左端的1
 16     int ansd, ans[MaxN];
 17 
 18     void init(int _n, int _m){
 19         n = _n;
 20         m = _m;
 21         for(int i = 0; i <= m; i++){
 22             S[i] = 0;
 23             U[i] = D[i] = i;
 24             L[i] = i-1;
 25             R[i] = i+1;
 26         }
 27         R[m] = 0; L[0] = m;
 28         size = m;
 29         memset(H, -1, sizeof(H));
 30     }
 31     void Link(int r, int c){
 32         size++;
 33         Col[size] = c, Row[size] = r;
 34         S[c]++;
 35         U[size] = U[c], D[size] = c;
 36         D[U[c]] = size;
 37         U[c] = size;
 38         if (H[r] != -1) {
 39             R[size] = H[r] ;
 40             L[size] = L[H[r]] ;
 41             R[L[size]] = size ;
 42             L[R[size]] = size ;
 43         }
 44         else
 45             H[r] = L[size] = R[size] = size ;
 46     }
 47     void remove(int c){//覆盖第c列。删除第c列及能覆盖到该列的行,防止重叠
 48         L[R[c]] = L[c]; R[L[c]] = R[c];
 49         for(int i = D[c]; i != c; i = D[i])
 50             for(int j = R[i]; j != i; j = R[j]){
 51                 U[D[j]] = U[j];
 52                 D[U[j]] = D[j];
 53                 --S[Col[j]];
 54             }
 55     }
 56     void resume(int c){
 57         for(int i = U[c]; i != c; i = U[i])
 58             for(int j = L[i]; j != i; j = L[j]){
 59                 ++ S[Col[j]];
 60                 U[D[j]] = j;
 61                 D[U[j]] = j;
 62             }
 63         L[R[c]] = R[L[c]] = c;
 64     }
 65     //d为递归深度
 66     bool dance(int d){
 67         if(R[0] == 0){
 68             ansd = d;
 69             return true;
 70         }
 71         int c = R[0];
 72         for(int i = R[0]; i != 0; i = R[i])
 73             if(S[i] < S[c])
 74                 c = i;
 75         remove(c);
 76         for(int i = D[c];i != c;i = D[i]){
 77             ans[d] = Row[i];
 78             for(int j = R[i]; j != i; j = R[j]) remove(Col[j]);
 79             if(dance(d+1)) return true;
 80             for(int j = L[i]; j != i; j = L[j]) resume(Col[j]);
 81         }
 82         resume(c);
 83         return false;
 84     }
 85 };
 86 DLX g;
 87 char s[15][15];
 88 int main(){
 89     int t;
 90     scanf("%d", &t);
 91     while(t--){
 92         for(int i = 0; i < 9; i++)
 93             scanf("%s", s[i]);
 94 
 95         g.init(81*9, 81+81+81+81);
 96 
 97         for(int i = 0; i < 9; i++)
 98             for(int j = 0; j < 9; j++){
 99                 int x = i, y = j, z = x/3*3+y/3, w = i*9+j;
100                 if(s[i][j] == '0'){
101                     for(int k = 1; k <= 9; k++){
102                         g.Link(w*9+k, w+1);
103                         g.Link(w*9+k, 81+x*9+k);
104                         g.Link(w*9+k, 162+y*9+k);
105                         g.Link(w*9+k, 243+z*9+k);
106                     }
107                 }
108                 else {
109                     int t = s[i][j]-'0';
110                     g.Link(w*9+t, w+1);
111                     g.Link(w*9+t, 81+x*9+t);
112                     g.Link(w*9+t, 162+y*9+t);
113                     g.Link(w*9+t, 243+z*9+t);
114                 }
115             }
116         g.dance(0);
117 
118         for(int i = 0; i < g.ansd; i++){
119             int t = g.ans[i];
120             int a = (t-1)/9, b = (t-1)%9+'1';
121             s[a/9][a%9] = b;
122         }
123         for(int i = 0; i < 9; i++)
124             puts(s[i]);
125     }
126     return 0;
127 }
View Code

 

DLX算法很容易,套个框架就能解决了,还能高效解决变形数独。用HDU4069,一个变形数独为例。

  1 //******************************************************//
  2 //hdu4069                                               //
  3 //******************************************************//
  4 #include <bits/stdc++.h>
  5 using namespace std;
  6 const int MaxM = 1000+10;
  7 const int MaxN = 1000+10;
  8 const int maxnode = MaxM*MaxN;
  9 struct DLX{
 10     int n, m, size;                 //行数,列数,总数
 11     int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
 12     int H[MaxN], S[MaxM];           //S记录该列剩余1的个数,H表示该行最左端的1
 13     int ansd, ans[MaxN];
 14     int temp[MaxN];
 15     int tot;
 16 
 17     void init(int _n, int _m){
 18         n = _n;
 19         m = _m;
 20         for(int i = 0; i <= m; i++){
 21             S[i] = 0;
 22             U[i] = D[i] = i;
 23             L[i] = i-1;
 24             R[i] = i+1;
 25         }
 26         R[m] = 0; L[0] = m;
 27         size = m;
 28         memset(H, -1, sizeof(H));
 29 
 30         tot = 0;
 31     }
 32     void Link(int r, int c){
 33         size++;
 34         Col[size] = c, Row[size] = r;
 35         S[c]++;
 36         U[size] = U[c], D[size] = c;
 37         D[U[c]] = size;
 38         U[c] = size;
 39         if (H[r] != -1) {
 40             R[size] = H[r] ;
 41             L[size] = L[H[r]] ;
 42             R[L[size]] = size ;
 43             L[R[size]] = size ;
 44         }
 45         else
 46             H[r] = L[size] = R[size] = size ;
 47     }
 48     void remove(int c){//覆盖第c列。删除第c列及能覆盖到该列的行,防止重叠
 49         L[R[c]] = L[c]; R[L[c]] = R[c];
 50         for(int i = D[c]; i != c; i = D[i])
 51             for(int j = R[i]; j != i; j = R[j]){
 52                 U[D[j]] = U[j];
 53                 D[U[j]] = D[j];
 54                 --S[Col[j]];
 55             }
 56     }
 57     void resume(int c){
 58         for(int i = U[c]; i != c; i = U[i])
 59             for(int j = L[i]; j != i; j = L[j]){
 60                 ++ S[Col[j]];
 61                 U[D[j]] = j;
 62                 D[U[j]] = j;
 63             }
 64         L[R[c]] = R[L[c]] = c;
 65     }
 66     //d为递归深度
 67     int dance(int d){
 68         if(R[0] == 0){
 69             ansd = d;
 70             for(int i = 0; i < ansd; i++)
 71                 ans[i] = temp[i];
 72             tot++;
 73             return tot;
 74         }
 75         int c = R[0];
 76         for(int i = R[0]; i != 0; i = R[i])
 77             if(S[i] < S[c])
 78                 c = i;
 79         remove(c);
 80         for(int i = D[c];i != c;i = D[i]){
 81             temp[d] = Row[i];
 82             for(int j = R[i]; j != i; j = R[j]) remove(Col[j]);
 83             if(dance(d+1) > 1) return tot;
 84             for(int j = L[i]; j != i; j = L[j]) resume(Col[j]);
 85         }
 86         resume(c);
 87         return tot;
 88     }
 89 };
 90 DLX g;
 91 
 92 int a[10][10];
 93 int gird[10][10];
 94 int d[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};//u,r,d,l
 95 void dfs(int x, int y, int color){
 96     gird[x][y] = color;
 97     for(int i = 0; i < 4; i++){
 98         int xx = x+d[i][0], yy = y+d[i][1];
 99         if((a[x][y] & (16<<i))== 0&&xx >= 0&& xx < 9&&yy >= 0&&yy <9&&gird[xx][yy] == -1)
100             dfs(xx, yy, color);
101     }
102     return ;
103 }
104 
105 int main(){
106     int T; scanf("%d", &T);
107     for(int ca = 1; ca <= T; ca++){
108         for(int i = 0; i < 9; i++)
109             for(int j = 0; j < 9; j++)
110                 scanf("%d", &a[i][j]);
111         memset(gird, -1, sizeof(gird));
112         int tt = 0;
113         for(int i = 0; i < 9; i++)
114             for(int j = 0; j < 9; j++)
115                 if(gird[i][j] == -1) dfs(i, j, tt++);
116 
117         g.init(81*9, 81*4);
118         for(int i = 0; i < 9; i++)
119             for(int j = 0; j < 9; j++){
120                 int t = (a[i][j]&15), w = i*9+j, x = i, y = j, z = gird[i][j];
121                 if(t){
122                     g.Link(w*9+t, w+1);
123                     g.Link(w*9+t, 81+x*9+t);
124                     g.Link(w*9+t, 162+y*9+t);
125                     g.Link(w*9+t, 243+z*9+t);
126                 }else {
127                     for(int k = 1; k <= 9; k++){
128                         g.Link(w*9+k, w+1);
129                         g.Link(w*9+k, 81+x*9+k);
130                         g.Link(w*9+k, 162+y*9+k);
131                         g.Link(w*9+k, 243+z*9+k);
132                     }
133                 }
134             }
135 
136         printf("Case %d:\n", ca);
137         int ret = g.dance(0);
138         if(ret == 1){
139             for(int i = 0; i < g.ansd; i++){
140                 int t = g.ans[i];
141                 int x = (t-1)/9, y = (t-1)%9+1;
142                 a[x/9][x%9] = y;
143             }
144             for(int i = 0; i < 9; i++){
145                 for(int j = 0; j < 9; j++)
146                     printf("%d", a[i][j]);
147                 puts("");
148             }
149         }
150         else if(ret > 1) puts("Multiple Solutions");
151         else puts("No solution");
152     }
153     return 0;
154 }
View Code

 

转载于:https://www.cnblogs.com/dirge/p/5206730.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业互联网上市公司.NET开发岗位来袭!!!

01公司简介2022 ABOUT /公司简介安徽容知日新科技股份有限公司&#xff08;股票代码&#xff1a;688768&#xff09;于2007年在合肥市成立&#xff0c;是一家工业互联网领域的高新技术企业&#xff0c;为客户提供设备智能运维平台解决方案和动设备预测性维护产品及服务。容知日…

【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记24 popovers弹窗

上几话中我们详细了解了几种segue&#xff0c;我们也了解到了多MVC模式的几种控制器&#xff0c;比如导航、选项卡和分栏&#xff0c;除了这三种多MVC的模式之外&#xff0c;还有一种popover&#xff0c;它跟其他三种不太一样。首先先来认识一下popover&#xff08;弹窗&#x…

React Native之didFocus和didBlur

1 didFocus和didBlur解释 didFocus - the screen focused (if there was a transition, the transition completed)didBlur - the screen unfocused (if there was a transition, the transition completed) didFocus是指当前页面第一次加载的时候会调用一次 didBlur是指当前…

python语法详解_解析 Python3 基础语法

行与缩进 python最具特色的就是使用缩进来表示代码块&#xff0c;不需要使用大括号 {} 。 缩进的空格数是可变的&#xff0c;但是同一个代码块的语句必须包含相同的缩进空格数。实例如下&#xff1a; if True: print ("True") else: print ("False") Color…

ASP.NET 6 中间件 - 介绍与基础

这是一个关于 .NET 6 中间件的系列文章。在这个系列中&#xff0c;我们将了解到什么是中间件&#xff0c;它能够做什么&#xff0c;以及我们为什么要使用它&#xff0c;并演示几种不同类型的中间件的实现。之后&#xff0c;我们会进一步了解中间件所在的管道&#xff0c;以及如…

数组的迭代数组里面每个对象添加属性值_JS数组和对象循环遍历的几种实现方式...

数组遍历1. 普通for循环let arr [1,2,3,4,5] for (let i 0; i < arr.length; i) {console.log(arr[i]) } // 输出结果 // 1 // 2 // 3 // 4 // 52. 优化普通for循环let arr [1,2,3,4,5] for(var j 0,len arr.length; j < len; j){console.log(arr[j]); }3. forEach循…

Blend4精选案例图解教程(三):一键拖拽

原文:Blend4精选案例图解教程&#xff08;三&#xff09;&#xff1a;一键拖拽拖拽效果&#xff0c;常规实现方法是定义MoveLeftDwon、MoveLeftUp、MouseMove事件&#xff0c;在Blend的世界里&#xff0c;实现对象的拖拽&#xff0c;可以不写一行代码&#xff0c;而且非常简单&…

python画气泡图_​用Python把图做的好看点:用Matplotlib画个好看的气泡图

我们继续来把简单的图形丢到极坐标&#xff0c;这次是气泡图和柱状图&#xff0c;临摹的对象是澎湃美数课这个图看起来很好看&#xff0c;原理其实很简单&#xff0c;把柱状图和气泡图从笛卡尔坐标系中转移到极坐标系中来就OK 我们开始本次的临摹吧 本期的主题如下&#xff1a;…

Asp.NET Core一个接口的多个实现如何基于当前HTTP请求注册

前言假设我们有三个Service类实现了同一接口&#xff0c;示例代码如下&#xff1a;public interface IService { } public class ServiceA : IService { } public class ServiceB : IService { } public class ServiceC : IService { }我们希望在运行时使用依赖注入指定其具体…

pytorch forward_【Pytorch部署】TorchScript

TorchScript是什么&#xff1f;TorchScript - PyTorch master documentation​pytorch.orgTorchScript是一种从PyTorch代码创建可序列化和可优化模型的方法。任何TorchScript程序都可以从Python进程中保存&#xff0c;并加载到没有Python依赖的进程中。我们提供了一些工具来增量…

兼容ie8 rgba()用法

今天遇到了一个问题&#xff0c;要在一个页面中设置一个半透明的白色div。这个貌似不是难题&#xff0c;只需要给这个div设置如下的属性即可&#xff1a; background: rgba(255,255,255,.1); 但是要兼容到ie8。这个就有点蛋疼了。因为ie8不支持rgba()函数。下面我们总结一下rgb…

python中的标识符能不能使用关键字_Python中的标识符不能使用关键字

Python中的标识符不能使用关键字答&#xff1a;√智慧职教: 检查客室座椅外观良好&#xff0c;确认?无破损答&#xff1a;坐垫 靠背关于投标报价时综合单价的确定&#xff0c;下列做法中正确的是()答&#xff1a;以项目特征描述为依据确定综合单价城市总体规划调查时&#xff…

C# WPF实战项目升级了

概述之前用Caliburn.Micro搭建的WPF实战项目&#xff0c;CM框架选用了 3.0.3&#xff0c;实际上CM框架目前最新版已经到4.0。173了&#xff0c;所有很有必须升级一下项目了. 本来打算把平台框架也直接升级到.NET 6 的&#xff0c;但是项目里面很多库不支持最新的平台版本&#…

ArcGIS Engine开发模板及C#代码

目 录 1. 模板 2. 代码 1. 模板 以下为AE开发软件自带的模板及代码,开发工具为VS 2012+ArcGIS Engine 10.2。 2. 代码 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; us…

高级iOS面试题

非标准答案 2 1: 类方法是可以直接通过类名直接调用&#xff0c;无需进行实例化对象。类方法是以开头2. 实例方法&#xff0c;需要显示实例化对象&#xff0c;为对象分配堆栈空间&#xff0c;并通过对象实例调用实例方法3. RUNTIME 是在程序运行过程动态对实例对象进行操作&…

dotTrace 6.1帮你理解SQL查询如何影响应用性能

dotTrace是JetBrains公司旗下的一款.NET应用程序性能瓶颈检测工具。该工具是ReSharper旗舰版的一部分&#xff0c;也可以单独安装。近日&#xff0c;dotTrace 6.1发布&#xff0c;主要增加了人们期待已久的SQL查询性能分析&#xff0c;开发人员可以通过它获得特定查询的执行时间…

mysql申请审核系统_Mysql审核工具archery

Mysql审核工具archery系统&#xff1a;Centos6.8ip:192.168.122.150安装Python和virtualenv编译安装[rootwww ~]# yum install wget gcc make zlib-devel openssl openssl-devel[rootwww src]# wget "https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz"[…

iOS——Core Animation 知识摘抄(二)

阴影 主要是shadowOpacity 、shadowColor、shadowOffset和shadowRadius四个属性 shadowPath属性 我们已经知道图层阴影并不总是方的&#xff0c;而是从图层内容的形状继承而来。这看上去不错&#xff0c;但是实时计算阴影也是一个非常消耗资源的&#xff0c;尤其是图层有多个子…

Blazor University (11)组件 — 替换子组件的属性

原文链接&#xff1a;https://blazor-university.com/components/replacing-attributes-on-child-components/替换子组件的属性源代码[1]到目前为止&#xff0c;我们已经了解了如何创建代码生成的属性[2]&#xff0c;以及如何捕获意外参数[3]。除了这两种技术之外&#xff0c;B…

HTTPS实现原理

HTTPS实现原理 HTTPS&#xff08;全称&#xff1a;Hypertext Transfer Protocol over Secure Socket Layer&#xff09;&#xff0c;是以安全为目标的HTTP通道&#xff0c;简单讲是HTTP的安全版。即HTTP下加入SSL层&#xff0c;HTTPS的安全基础是SSL。其所用的端口号是443。…