LeetCode 37. 解数独(搜索+剪枝)

2024-04-15 23:08
文章标签 leetcode 搜索 37 解数 剪枝

本文主要是介绍LeetCode 37. 解数独(搜索+剪枝),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

思路:

  • 用数组 x , y , z x,y,z x,y,z记录每一行,每一列,和每一个 3 ∗ 3 3*3 33小块里面0~9的使用情况。使用状态,0代表使用了,1代表没有使用。
  • 然后搜索的时候遍历每一个格子,找到里面可选数字最少的那一个(也就是其行、列、小块的数字使用情况状态的与值中1最少的那个。
  • 直到搜索到每个格子都被填完
  • 加几个剪枝:如果中间有格子什么数都填不了,那就直接返回 f a l s e false false
class Solution {
public:char s[105];int x[105],y[105],z[105];int X[105],Y[105],Z[105];int f[1005];int cnt[1005];int gx,gy,gz;int get_cnt(int i) {int num = 0;while(i) {num++;i -= i & -i;}return num;}void get(int i) {gx = X[i];gy = Y[i];gz = Z[i];}void work(int i,int now) {get(i);x[gx] ^= (1 << now);y[gy] ^= (1 << now);z[gz] ^= (1 << now);}bool dfs(int ans) {if(!ans) return true;int k = 10,w,t = -1;for(int i = 0;i < 81;i++) {if(s[i] == '.') {get(i);w = x[gx] & y[gy] & z[gz];if(w == 0) return false;if(cnt[w] < k) {k = cnt[w];t = i;}}}if(t == -1) return false;get(t);w = x[gx] & y[gy] & z[gz];while(w) {int now = f[w & -w];s[t] = now + '1';work(t,now);if(dfs(ans - 1)) return true;work(t,now);w -= w & -w;s[t] = '.';}return false;}void solve(vector<vector<char>>&board) {for(int i = 0;i < 9;i++) {x[i] = (1 << 9) - 1;y[i] = (1 << 9) - 1;z[i] = (1 << 9) - 1;}int ans = 0;for(int i = 0;i < 9;i++) {for(int j = 0;j < 9;j++) {s[i * 9 + j] = board[i][j];}}for(int i = 0;i < 81;i++) {if(s[i] != '.') work(i,s[i] - '1');else ans++;}dfs(ans);for(int i = 0;i < 9;i++) {for(int j = 0;j < 9;j++) {board[i][j] = s[i * 9 + j];}}}void init() {for(int i = 0;i < (1 << 9);i++) cnt[i] = get_cnt(i);for(int i = 0;i < 81;i++) {X[i] = i / 9;Y[i] = i % 9;Z[i] = X[i] / 3 * 3 + Y[i] / 3;}for(int i = 0;i < 9;i++) f[1 << i] = i;}void solveSudoku(vector<vector<char>>& board) {init();solve(board);}
};

这篇关于LeetCode 37. 解数独(搜索+剪枝)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907185

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &