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 + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...
随机推荐
- STM32应用实例十五:STM32的ADC通道间干扰的问题
最近我们在开发一个项目时,用到了MCU自带的ADC,在调试过程中发现通道之间村在相互干扰的问题.以前其实也用过好几次,但要求都不高所以没有太关注,此次因为物理量的量程较大,所以看到了变化. 首先来说明 ...
- Modbus库开发笔记之五:Modbus RTU Slave开发
Modbus在串行链路上分为Slave和Master,这一节我们就来开发Slave.对于Modbus RTU从站来说,需要实现的功能其实与Modbus TCP的服务器端是一样的.其操作过程也是一样的. ...
- ionic3 点击输入 框弹出白色遮罩 并把 界面顶到上面
这个蛋疼 问题 ,在android 上面遇到这种情况 ,键盘弹出的时候 总有一个白色的遮罩在后面出现,网上查了很久都没发现原因. 偶然发现一个方法 ,试下了下 问题解决了. 代码如下: IonicMo ...
- 20165314 学习基础和C语言基础调查
技能学习心得 你有什么技能比大多人(超过90%以上)更好?针对这个技能的获取你有什么成功的经验?与老师博客中的学习经验有什么共通之处? 从小我的父母就逼着我学习很多技能,比如钢琴,围棋,书法等,不过很 ...
- 监控CPU使用率并发送报警邮件
#!/bin/bash DATE=$(date +%F" "%H:%M) #只支持centos6 IP=$(ifconfig eth0 | awk -F '[ :]+' '/ine ...
- python unittest套件,修改为失败重新执行
#套件,修改为失败重新执行 import time import unittest from unittest.suite import _isnotsuite class Suit(unittest ...
- jQuery常见案例
jQuery常见案例 通过jQuery实现全选,反选取消: 选择 地址 端口 1.1.1.1 80 1.1.1.1 80 1.1.1.1 80 1.1.1.1 80 代码实现 <body> ...
- 如何保证Redis的高并发
单机的redis几乎不太可能说QPS超过10万+,一般在几万. 除非一些特殊情况,比如你的机器性能特别好,配置特别高,物理机,维护做的特别好,而且你的整体的操作不是太复杂. Redis通过主从架构,实 ...
- JVM 方法区内存扩大 以及开启GC
因为应用使用了OSGi框架,<深入理解JAVA虚拟机>中对使用OSGi时可能产生的方法区溢出有所描述 第一部分: 第二部分 可见,OSGi会动态生成大量Class,在OSGi中,即使是同一 ...
- [转] getBoundingClientRect判断元素是否可见
getBoundingClientRect介绍 getBoundingClientRect获取元素位置 getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视 ...