POJ 2726、POJ3074 :数独(二进制DFS)
题目链接:https://ac.nowcoder.com/acm/contest/1014/B
题目描述
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
输入描述:
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
输出描述:
For each test case, print a line representing the completed Sudoku puzzle.
示例1
输入
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
输出
527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936
分析
- 可以从左上角一行一行扫描到右下角,对于每一个块列举每一种可能,然后从每个可能出发继续深度遍历直到发现有一个块没有数字可以填时停止
- 如何储存每一块可以填写的数字?可以利用九位二进制数来表示每一行,每一列,每个九宫格的数字填写情况,然后直接对这三个数字做按位与运算就可以得到某一具体块可以填的数字了。
- 这里直接用
bitset,对于每一个结果,直接遍历一下就可以了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char str[10][10];
int row[9], col[9], grid[9], cnt[512], num[512], tot;
inline int g(int x, int y) {
return ((x / 3) * 3) + (y / 3);
}
inline void flip(int x, int y, int z) {
row[x] ^= 1 << z;
col[y] ^= 1 << z;
grid[g(x, y)] ^= 1 << z;
}
bool dfs(int now) {
if (now == 0) return 1;
int temp = 10, x, y;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++) {
if (str[i][j] != '.') continue;
int val = row[i] & col[j] & grid[g(i, j)];
if (!val) return 0;
if (cnt[val] < temp) {
temp = cnt[val];
x = i, y = j;
}
}
int val = row[x] & col[y] & grid[g(x, y)];
for (; val; val -= val&-val) {
int z = num[val&-val];
str[x][y] = '1' + z;
flip(x, y, z);
if (dfs(now - 1)) return 1;
flip(x, y, z);
str[x][y] = '.';
}
return 0;
}
int main() {
for (int i = 0; i < 1 << 9; i++)
for (int j = i; j; j -= j&-j) cnt[i]++;
for (int i = 0; i < 9; i++)
num[1 << i] = i;
char s[100];
while (~scanf("%s", s) && s[0] != 'e') {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++) str[i][j] = s[i * 9 + j];
for (int i = 0; i < 9; i++) row[i] = col[i] = grid[i] = (1 << 9) - 1;
tot = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (str[i][j] != '.') flip(i, j, str[i][j] - '1');
else tot++;
dfs(tot);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++) s[i * 9 + j] = str[i][j];
puts(s);
}
}
POJ 2726、POJ3074 :数独(二进制DFS)的更多相关文章
- POJ 2676/2918 数独(dfs)
思路:记录每行每列每一个宫已经出现的数字就可以.数据比較弱 另外POJ 3074 3076 必须用剪枝策略.但实现较麻烦,还是以后学了DLX再来做吧 //Accepted 160K 0MS #incl ...
- POJ - 2676 Sudoku 数独游戏 dfs神奇的反搜
Sudoku Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smalle ...
- poj Sudoku(数独) DFS
Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13665 Accepted: 6767 Special ...
- POJ 1321-棋盘问题(DFS 递归)
POJ 1321-棋盘问题 K - DFS Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I6 ...
- poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析
题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...
- POJ 2676 Sudoku (数独 DFS)
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14368 Accepted: 7102 Special Judg ...
- poj 2676 数独问题 dfs
题意:完成数独程序,数独要求每行每列且每个3*3矩阵都必须是1~9的数字组成. 思路:dfs 用row[i][n] 记录第i行n存在 用col[j][n] 记录第j列n存在 grid[k][n] 记 ...
- 数独求解 DFS && DLX
题目:Sudoku 题意:求解数独.从样例和结果来看应该是简单难度的数独 思路:DFS 设置3个数组,row[i][j] 判断第i行是否放了j数字,col[i][j] 判断第i列是否放了j数字.squ ...
- POJ 2386——Lake Counting(DFS)
链接:http://poj.org/problem?id=2386 题解 #include<cstdio> #include<stack> using namespace st ...
- POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25904 Accepted: 7682 Descr ...
随机推荐
- 总结(6)--- python基础知识点小结(细全)
==================================================================================================== ...
- Redis本地安装以及使用(详细教程)
Redis 安装 Windows 下载安装 Redis默认端口:6379 整个过程如下: 1.下载连接 https://github.com/tporadowski/redis/releases Re ...
- 解决This application failed to start because cannot find or load the qt platform plugin 'xcb'
问题描述: 在使用linux系统训练自己的数据集合时,出现了上述问题,首先第一个想法就是先Google,但是在看了一些国内外的文章后依然没有将问题解决 问题原因: 这是由于这几天我在安装cuda.cu ...
- 27、Type关键字
1.是什么? type是go语法里额重要而且常用的关键字,type绝不只是对应于C/C++中的typeof.搞清楚type的使用,就容易理解Go语言中的核心概念struct.interface.函数等 ...
- 一个ssh无法远程登录的问题跟踪解决
用户反馈龙芯服务器系统loongnix-server使用root用户ssh远程登录,有时候可以有时候又无法登录,频繁出现错误:Permission denied,please try again.我分 ...
- 【算法】Java版
二分查找算法 二分查找算法(Binary Search Algorithm)是一种在有序数组中查找特定元素的搜索算法.该算法的基本思想是将数组从中间分成两部分,然后与目标元素进行比较,进而确定目标元素 ...
- C# 获取另一程序控件,改变值,触发事件
[DllImport("User32.dll", EntryPoint = "FindWindow")]private static extern IntPtr ...
- 从零玩转Nginx-从零玩转nginx
title: 从零玩转Nginx date: 2023-05-13 23:08:49.074 updated: 2023-05-13 23:17:26.474 url: https://www.yby ...
- 文心一言 VS 讯飞星火 VS chatgpt (171)-- 算法导论13.2 4题
四.用go语言,证明:任何一棵含n个结点的二叉搜索树可以通过 O(n)次旋转,转变为其他任何一棵含n个结点的二叉搜索树.(提示:先证明至多n-1次右旋足以将树转变为一条右侧伸展的链.) 文心一言: 这 ...
- MS17-010(永恒之蓝)漏洞分析与复现
一.漏洞简介1.永恒之蓝介绍:永恒之蓝漏洞(MS17-010),它的爆发源于 WannaCry 勒索病毒的诞生,该病毒是不法分子利用NSA(National Security Agency,美国国家安 ...