Sudoku POJ - 3076 (dfs+剪枝)
Description

Write a Sudoku playing program that reads data sets from a text file.
Input
Output
Sample Input
- --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-
Sample Output
- FPAHMJECNLBDKOGI
- OJMIANBDPKCGFLHE
- LNDKGFOIJEAHMBPC
- BGCELKHPOFIMAJDN
- MFHBELPOACKJGNID
- CILNKDGAHBMOPEFJ
- DOGPIHJMFNLECAKB
- JEKAFCNBGIDPLHOM
- EBOFPMIJDGHLNKCA
- NCJDHBAEKMOFIGLP
- HMPLCGKFIAENBDJO
- AKIGNODLBPJCEFMH
- KDEMJIFNCHGAOPBL
- GLBCDPMHEONKJIAF
- PHNOBALKMJFIDCEG
- IAFJOECGLDPBHMNK
题意:就是让每行,每列,每个4*4的十六宫格中A~P只出现一次。输出16*16的宫格信息。
思路:我总感觉这题用dancing links会好做很多
①肯定是选择可填入的字母最少的位置开始dfs,这样分支比较少
②如果一个位置只剩一个字母可以填,就填上这个字母(废话)
③如果所有的字母不能填在该行(列、十六宫格),立刻回溯
④如果某个字母只能填在该行(列、十六宫格)的某处,立刻填写
首先除了dfs的结束条件外,一次写下对位置的②剪枝,对行,列,十六宫格的③、④剪枝,因为②、④剪枝填了一个字母,需要再次判断结束条件,
然后就是对可能性最小的位置进行dfs
(代码参考网上,侵删)
- #include<iostream>
- #include<string.h>
- #include<cstdio>
- using namespace std;
- int maps[][];
- int table[][];
- int num;
- void put_in(int x,int y,int k)
- {
- num++;
- maps[x][y] = k;
- table[x][y] |= <<k;
- for(int i=; i<=; i++)
- {
- table[i][y] |= <<k;
- table[x][i] |= <<k;
- }
- int r = (x-)/*+;
- int c = (y-)/*+;
- for(int i=; i<; i++)
- {
- for(int j=; j<; j++)
- {
- table[r+i][c+j] |= <<k;
- }
- }
- }
- int _count(int x)
- {
- for(int i=; x; i++)
- {
- if(x & )
- {
- if(x>> == )
- return i;
- return -;
- }
- x >>= ;
- }
- return -;
- }
- int row(int x,int k)
- {
- int t = -;
- for(int y=; y<=; y++)
- {
- if(maps[x][y] == k)
- return -;
- if(maps[x][y] >= )
- continue;
- if((table[x][y]&<<k) == )
- {
- if(t != -)
- return -;
- t = y;
- }
- }
- if(t != -)
- return t;
- return -;
- }
- int col(int y,int k)
- {
- int t = -;
- for(int x=; x<=; x++)
- {
- if(maps[x][y] == k)
- return -;
- if(maps[x][y] >= )
- continue;
- if((table[x][y]&<<k) == )
- {
- if(t != -)
- return -;
- t = x;
- }
- }
- if(t != -)
- return t;
- return -;
- }
- void cuble(int r,int c,int k,int &x,int &y)
- {
- x = -;
- for(int i=; i<; i++)
- {
- for(int j=; j<; j++)
- {
- if(maps[i+r][j+c] == k)
- {
- x=-;
- return;
- }
- if(maps[i+r][j+c] >= )
- continue;
- if((table[i+r][j+c]&<<k) == )
- {
- if(x != -)
- {
- x=-;
- return;
- }
- x = i;
- y = j;
- }
- }
- }
- }
- int cal(int x)
- {
- int cnt = ;
- while(x)
- {
- if(x&)
- cnt++;
- x >>= ;
- }
- return cnt;
- }
- bool dfs()
- {
- if(num == )
- {
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- printf("%c",maps[i][j]+'A');
- }
- puts("");
- }
- puts("");
- return ;
- }
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- if(maps[i][j] >= )
- continue;
- int k = _count(table[i][j]);
- if(k != -)
- put_in(i,j,k);
- }
- }
- for(int x=; x<=; x++)
- {
- for(int k=; k<; k++)
- {
- int y = row(x,k);
- if(y == -)
- return ;
- if(y != -)
- put_in(x,y,k);
- }
- }
- for(int y=; y<=; y++)
- {
- for(int k=; k<; k++)
- {
- int x = col(y,k);
- if(x == -)
- return ;
- if(x != -)
- put_in(x,y,k);
- }
- }
- for(int r=; r<=; r+=)
- {
- for(int c=; c<=; c+=)
- {
- for(int k=; k<; k++)
- {
- int x,y;
- cuble(r,c,k,x,y);
- if(x == -)
- return ;
- if(x != -)
- put_in(r+x,c+y,k);
- }
- }
- }
- if(num == )
- {
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- printf("%c",maps[i][j]+'A');
- }
- puts("");
- }
- puts("");
- return ;
- }
- int t_num;
- int t_maps[][];
- int t_table[][];
- t_num = num;
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- t_maps[i][j] = maps[i][j];
- t_table[i][j] = table[i][j];
- }
- }
- int mx,my,mn=;
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- if(maps[i][j]>=)
- continue;
- int r = - cal(table[i][j]);
- if(r < mn)
- {
- mn = r;
- mx = i,my = j;
- }
- }
- }
- for(int k=; k<; k++)
- {
- if((table[mx][my] & <<k) == )
- {
- put_in(mx,my,k);
- if(dfs())
- return ;
- num = t_num;
- for(int i=; i<=; i++)
- {
- for(int j=; j<=; j++)
- {
- maps[i][j] = t_maps[i][j];
- table[i][j] = t_table[i][j];
- }
- }
- }
- }
- return ;
- }
- int main()
- {
- char s[];
- while(~scanf("%s",s))
- {
- num = ;
- memset(table,,sizeof(table));
- for(int j=; j<=; j++)
- {
- if(s[j-]!='-')
- put_in(,j,s[j-]-'A');
- else
- maps[][j] = -;
- }
- for(int i=; i<=; i++)
- {
- scanf("%s",s);
- for(int j=; j<=; j++)
- {
- if(s[j-]!='-')
- put_in(i,j,s[j-]-'A');
- else
- maps[i][j] = -;
- }
- }
- dfs();
- }
- }
Sudoku POJ - 3076 (dfs+剪枝)的更多相关文章
- POJ 3009 DFS+剪枝
POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...
- 2018 Multi-University Training Contest 4 Problem J. Let Sudoku Rotate 【DFS+剪枝+矩阵旋转】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6341 Problem J. Let Sudoku Rotate Time Limit: 2000/100 ...
- Sudoku POJ - 3076
Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 5769 Accepted: 2684 Descripti ...
- HDU-6341 Problem J. Let Sudoku Rotate(dfs 剪枝)
题目:有一个4*4*4*4的数独,每一横每一竖每一个小方块中都无重复的字母,即都为0-9,A-F..有一个已经填好的数独,若干个4*4的方块被逆时针拧转了若干次,问拧转回来至少需要多少次. 分析:很明 ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
- poj 1564 Sum It Up | zoj 1711 | hdu 1548 (dfs + 剪枝 or 判重)
Sum It Up Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Sub ...
- (简单) 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
3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...
随机推荐
- 一篇文章教你读懂UI绘制流程
最近有好多人问我Android没信心去深造了,找不到好的工作,其实我以一个他们进行回复,发现他们主要是内心比较浮躁,要知道技术行业永远缺少的是高手.建议先阅读浅谈Android发展趋势分析,在工作中, ...
- 信息摘要算法之六:HKDF算法分析与实现
HKDF是一种特定的键衍生函数(KDF),即初始键控材料的功能,KDF从其中派生出一个或多个密码强大的密钥.在此我们想要描述的是基于HMAC的HKDF. 1.HKDF概述 密钥派生函数(KDF)是密码 ...
- mysql服务器没有响应
第一步删除c:\windowns下面的my.ini(可以先改成其它的名字也行) 第二步打开对应安装目录下\mysql\bin\winmysqladmin.exe 输入用户名 和密码(也可以忽略此步) ...
- Zookeeper客户端Curator的使用,简单高效
Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.引入依赖: ...
- 【sqli-labs】Less17
Less17: POST注入,UPDATE语句,有错误回显 新知识点: 1. update注入方法 参考:http://www.mamicode.com/info-detail-1665678.htm ...
- PDF裁剪页面,PDF怎么裁剪页面的方法
PDF文件要怎么裁剪页面呢,是不是有很多的小伙们想知道呢,当打开一个PDF文件的时候如果一个页面中有很多的空白页面就会影响文件的美观与使用,今天小编就为大家分享一下小编的裁剪页面的方法. 操作软件:迅 ...
- Nginx详解二十一:Nginx深度学习篇之配置苹果要求的openssl后台HTTPS服务
配置苹果要求的证书: 1.服务器所有的连接使用TLS1.2以上的版本(openssl 1.0.2) 2.HTTPS证书必须使用SHA256以上哈希算法签名 3.HTTPS证书必须使用RSA2048位或 ...
- js中json对象数组按对象属性排序(sort方法)---2(根据拼音排序汉字和排序英文)
本例主要实现 中文汉字按拼音排序的方法和英文按照首字母排序的方法. 要排序的数据: //要排序的数据 let data = [ {chinese: '蔡司', english: 'Chase'}, { ...
- .tar.xz文件的解压方法
废话不多说: 直接看 方法一: tar -xvJf ***.tar.gz 方法二: 先减压成 .tar 格式的文件, 再解压 .tar #xz是一个工具, 系统中没有安装,需要下载 xz -d *** ...
- c++ 链表基础功能实现
#include<stack> struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* CreateListNode ...