POJ3074 Sudoku(lowbit优化搜索)

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 3 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .
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.

样例输入
.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
来源
Stanford Local 2006

题解:
这里使用了lowbit来优化当前的方案,存入二进制数后可以用Lowbit搜索每一位。
所以这说不定就是除了某d开头算法外数独较快的解法了吧。

#include <bits/stdc++.h>
#define lowbit(x) (x & (-x))
using namespace std;
char ch[12][12];
int hang[12], lie[12], gong[12], cnt[1200], num[1200], tot;
int get(int x, int y) { return (x / 3) * 3 + y / 3; }
void flip(int x, int y, int z) {
    hang[x] ^= (1 << z);
    lie[y] ^= (1 << z);
    gong[get(x, y)] ^= (1 << z);
    return;
}
bool dfs(int now) {
    if (!now)
        return 1;
    int mn = 10, x, y;
    for (int i = 0; i < 9; i++)
        for (int j = 0; j < 9; j++) {
            if (ch[i][j] != '.')
                continue;
            int val = hang[i] & lie[j] & gong[get(i, j)];
            if (!val)
                return 0; //矛盾,回退
            if (cnt[val] < mn) {
                mn = cnt[val];
                x = i, y = j;
            }
        }
    int val = hang[x] & lie[y] & gong[get(x, y)];
    for (int i = val; i; i -= lowbit(i)) {
        int which = num[lowbit(i)];
        ch[x][y] = '1' + which;
        flip(x, y, which);
        if (dfs(now - 1))
            return 1;
        flip(x, y, which);
        ch[x][y] = '.';
    }
    return 0;
}
char yyh[12000];
signed main() {
    for (int i = 0; i < (1 << 9); i++)
        for (int j = i; j; j -= lowbit(j))
            cnt[i]++; //有几个1
    for (int i = 0; i < 9; i++)
        num[1 << i] = i;
    while (scanf("%s", yyh) && yyh[0] != 'e') {
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                ch[i][j] = yyh[i * 9 + j];
        for(int i=0;i<9;i++) hang[i]=lie[i]=gong[i]=(1<<9)-1;
        tot=0;
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                if (ch[i][j]!='.') flip(i,j,ch[i][j]-'1');
                else tot++;
        dfs(tot);
        for(int i=0;i<9;i++) for(int j=0;j<9;j++) cout<<ch[i][j];
        puts("");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/wky32768/p/10750778.html

时间: 2024-11-01 16:13:19

POJ3074 Sudoku(lowbit优化搜索)的相关文章

倒油问题,广度优化搜索,java

有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶)和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢? class DumpOilBFS: import cn.hncu.sreach.putOil.common.Bucket; import cn.hncu.sreach.putOil.common.DumpCase; import cn.hncu.sreach.putOil.common.MySet; /* 有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,

Codeforces 327E Axis Walking (状压dp lowbit优化)

E. Axis Walking time limit per test:3 seconds memory limit per test:512 megabytes Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub lives at point 0 and Iahubina at point d. Iahub has n positive integ

U盘便携式hexo&amp;博客搭建&amp;极速纯净低bug主题推荐&amp;部署到coding&amp;SEO优化搜索

指南:U盘便携式hexo&博客搭建&极速纯净低bug主题推荐&部署到coding&SEO优化搜索 U盘便携式hexo随处写博客 简述:在任意一台联网的电脑上续写hexo博客,一个U盘+几个网站即可搞定.便携式hexo,其免去Nodejs 和 Git 的安装和配置还包含了配置和懒人脚本.好处就是省事.简单.方便 便携式hexo下载及使用方法,由 HEXO Portable | 比特萌信息技术 免费提供服务.(这里使用的版本是1.0.3) 几个网站: 折腾选用:hexo中文文档

剪枝算法--优化搜索(转载)

转载于:http://princetonboy.ycool.com/post.2805302.html [摘要]本文讨论了搜索算法中“剪枝”这一常见的优化技巧. 首先由回溯法解决迷宫问题展开论述,介绍了什么是剪枝; 而后分析剪枝的三个原则正确.准确.高效,并分别就剪枝的两种思路:可行性剪枝及最优性剪枝,结合例题作进一步的阐述; 最后对剪枝优化方法进行了一些总结. [关键字]搜索.优化.剪枝.时间复杂度 引论 在竞赛中,我们有时会碰到一些题目,它们既不能通过建立数学模型解决,又没有现成算法可以套用

nyoj546 Divideing Jewels (动态规划+优化||搜索+剪枝)

题意:给你n个宝珠,然后给宝珠个价值,价值范围[1,10],能不能均分给两个人. 输入的数据:价值分别为1,2,3...10的有多少个. 这道题和队友做了好久最终在结束前5分钟AC..第一次简单的动规结果TLE 不过和队友认为一定是动规.就在想如何优化,想到如果某个价值的个数有偶数个就不判断,奇数个就存入数组. 结果还是wr...我们不放弃啊...为就想着写几组数组,当0 2 0 1 0 0 0 0 0 0 输出结果为不能,显然答案是能的. 还剩下不到20分钟了.这个时候就是靠感觉了,直接就写如

Python初学练习02:简易通讯录-优化搜索功能

#!/usr/bin/env pythonimport tab,os,sysexitcheck = Falselistfile = 'Addresslist.data'Dictionary = {}#with open(listfile,'a') as datafiledatafile=file(listfile,'r')datafile.seek(0)for line in datafile.readlines(): id=line.split()[0] name=line.split()[1

POJ-3278 广度优化搜索入门

#include<stdio.h> #include<stdlib.h> struct node{ int x; int s; }s[400005]; int main(){ int n,m,book[400005]={0}; scanf("%d %d",&n,&m); if(n==m) printf("0\n"); else{ int tail=1,head=1; s[tail].x=n; s[tail++].s=0; bo

5.terms搜索多个值以及多值搜索结果优化

主要知识点 terms搜索多个值,并和term的比较 一.term和terms terms是在这个字段中搜索多个值,相当于sql中的in语法 (select * from tbl where col in ("value1", "value2")) term: {"field": "value"} terms: {"field": ["value1", "value2"

[专题练习] Part1 搜索

一.DFS(深度优先搜索) 过于水略过. 二.BFS(广度优先搜索) 同上. 三.记忆化 记忆化搜索,就是我们的状态会重复利用,为了防止状态的重复计算耗费不必要的时间,我们可以把这个状态的结果记录下来,然后查询表中的结果就行了. 一般来所,记忆化搜索是和DP等价的.如果递推的DP不好写,可以考虑用记忆化搜索实现,但是因为是递归,所以常数略大.记忆化搜索有明显的优点,就是可以不用考虑状态在哪里终止,只用知道状态会终止就行了. 四.搜索剪枝 这是一门博大精深的学问, 通常用于解决搜索时间复杂度过高的