博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
noip2009靶形数独题解
阅读量:5133 次
发布时间:2019-06-13

本文共 3680 字,大约阅读时间需要 12 分钟。

    靶形数独是一个经典的NP完全问题,没有多项式算法,显然需要搜索,递归回溯会优于枚举。然而此题数据范围大,如果朴素搜索显然肯定TLE,于是我们就需要一些优化。

    1.在搜索中,每次我们都需要查找当前格子的可填数字,如果用二进制数集存储的话,可以大大减少运行时间。对于一个格子(x,y),可选数字为x行、y列、所在九宫格的可选数字集合的交集,用二进制存储,利用位运算实现,可过75%的数据。

    2.贪心优化。如果是人做数独,必然先考虑可填数小的格子,本题也是如此。如果只是简单地从上往下搜索,会产生很多无用的状态,如果先填可填数小的格子,可以给其它的格子更多的限制,剪去许多不可行的分支。前面填的格子可能会对后面产生影响,因此可以每次都更新一遍,然后找到最小值。

    具体程序见下面。

    这题还有一个方法,用DLX(dancing links)。简单的说, Dancing Links 主要是用双向十字链表来存储稀疏矩阵,来达到在搜索中的优化。在搜索问题中,所需要存储的矩阵往往随着递归的加深会变得越来越稀疏,这种情况用Dancing Links 来存储矩阵,往往可以取得非常好的效果。DLX就是利用了双向链表的删除和重新插入的方便快速,把矩阵不断删除一些行和列,回溯时再恢复,使得在递归回溯中得到相当快的速度。具体程序也就不实现了。这方面的典型题目就是精确覆盖问题,很多数独问题也可以转化为此类问题。poj3074就可以用此方法。DLX是很通用的搜索优化方法,有兴趣的话,可以自己查找资料,这是一篇中文版的论文。

   

View Code
1 const d:array[1..9,1..9]of longword=((1,1,1,1,1,1,1,1,1),   2                                    (1,2,2,2,2,2,2,2,1),   3                                    (1,2,3,3,3,3,3,2,1),   4                                    (1,2,3,4,4,4,3,2,1),   5                                    (1,2,3,4,5,4,3,2,1),   6                                    (1,2,3,4,4,4,3,2,1),   7                                    (1,2,3,3,3,3,3,2,1),   8                                    (1,2,2,2,2,2,2,2,1),   9                                    (1,1,1,1,1,1,1,1,1));  10       c:array[1..9,1..9]of longword=((1,1,1,2,2,2,3,3,3),  11                                     (1,1,1,2,2,2,3,3,3),  12                                     (1,1,1,2,2,2,3,3,3),  13                                     (4,4,4,5,5,5,6,6,6),  14                                     (4,4,4,5,5,5,6,6,6),  15                                     (4,4,4,5,5,5,6,6,6),  16                                     (7,7,7,8,8,8,9,9,9),  17                                     (7,7,7,8,8,8,9,9,9),  18                                     (7,7,7,8,8,8,9,9,9));  19 var i,j,n,m,k,l,min,x,y:longword;  20     a:array[0..9,0..9]of longword;  21     s1,s2,s3:array[0..9]of longword;  22     p:array[0..9,0..9]of boolean;  23     bo:boolean;  24     ans:longint;  25 function getnum(k:longword):longword;  26 begin  27   k:=(k and $55555555)+((k shr 1)and $55555555);  28   k:=(k and $33333333)+((k shr 2)and $33333333);  29   k:=(k and $0F0F0F0F)+((K shr 4)and $0F0F0F0F);  30   K:=(k and $00FF00FF)+((k shr 8)and $00FF00FF);  31   k:=(k and $0000FFFF)+((k shr 16)and $0000FFFF);  32   exit(k);  33 end;  34 procedure getmin(var x1,y1:longword);  35 var i,j,k,min,l:longword;  36 begin  37   min:=maxlongint;  38   for i:=1 to 9 do  39    for j:=1 to 9 do  40    if (a[i,j]=0) then  41    begin  42     k:=s1[i] or s2[j] or s3[c[i,j]];  43     k:=k xor 511;  44     k:=getnum(k);  45     if (k
0 do 64 begin 65 l:=k and -k; 66 k:=k-l; 67 bak1:=s1;bak2:=s2;bak3:=s3; 68 s1[x]:=s1[x] or l; 69 s2[y]:=s2[y] or l; 70 s3[c[x,y]]:=s3[c[x,y]] or l; 71 case l of 72 1:j:=1; 73 2:j:=2; 74 4:j:=3; 75 8:j:=4; 76 16:j:=5; 77 32:j:=6; 78 64:j:=7; 79 128:j:=8; 80 256:j:=9; 81 end; 82 a[x,y]:=j; 83 go(step+1); 84 a[x,y]:=0; 85 s1:=bak1;s2:=bak2;s3:=bak3; 86 end; 87 end; 88 begin 89 assign(input,'sudoku.in');reset(input); 90 assign(output,'sudoku.out');rewrite(output); 91 fillchar(a,sizeof(a),0); 92 m:=81; 93 for i:=1 to 9 do 94 for j:=1 to 9 do 95 begin 96 read(a[i,j]); 97 if a[i,j]<>0 then 98 begin 99 s1[i]:=s1[i] or(1 shl(a[i,j]-1)); 100 s2[j]:=s2[j] or(1 shl(a[i,j]-1)); 101 s3[c[i,j]]:=s3[c[i,j]] or(1 shl(a[i,j]-1)); 102 dec(m); 103 end; 104 end; 105 ans:=-1; 106 go(1); 107 writeln(ans); 108 close(input);close(output); 109 end.

转载于:https://www.cnblogs.com/N-C-Derek/archive/2011/10/20/2219335.html

你可能感兴趣的文章
STM32单片机使用注意事项
查看>>
032. asp.netWeb用户控件之一初识用户控件并为其自定义属性
查看>>
移动开发平台-应用之星app制作教程
查看>>
leetcode 459. 重复的子字符串(Repeated Substring Pattern)
查看>>
springboot No Identifier specified for entity的解决办法
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>
Flask 系列之 SQLAlchemy
查看>>
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
[HDU3683 Gomoku]
查看>>
下一代操作系统与软件
查看>>
[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
查看>>
Python IO模型
查看>>
DataGridView的行的字体颜色变化
查看>>