POJ3076 Sudoku

  • 本题为16*16宫格
  • 剪枝见代码
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=; #define res register int
int map[N][N];
unsigned short t[N][N];
//table[i,j](二进制)表示(i,j)可以填的数,0可填,1不可填
int filled(); inline void my_fill(int x,int y,int a)//(x,y)填a
{
filled++;
map[x][y]=a;
t[x][y] |=<<(a-);
for(res i= ; i< ; i++)
t[x][i] |=<<(a-),
t[i][y] |=<<(a-);
int r=x/*,c=y/*;//(r,c)表示(x,y)所在的16宫格的左上角的格子,(从(0,0)开始)
for(res i= ; i< ; i++)
for(res j= ; j< ; j++) t[r+i][j+c] |=<<(a-);
} //判断x中0的个数是否只有1个
int count_zero(unsigned short x)
{
int p(-);
for(int i=;x;i++)
{
if(x&==)
{
if(p!=-) return -;
p=i;
}
x>>=;
}
return p;
} //第x行,数字k+1,返回>0表示唯一可填的k+1的位置,-1表示有多个可以填的位置或已经填过,-2不能填
inline int col(int x,int k)
{
int p(-);
for(res y= ; y< ; y++)
{
if(map[x][y]==k+) return -;//已经填过
if(map[x][y]>) continue;
if((t[x][y]&(<<k))==)
{
if(p!=-) return -;//多次出现
p=y;
}
}
if(p!=-) return p;
return -;
} //第y列,数字k
inline int row(int y,int k)
{
int p=-;
for(res x= ; x< ; x++)
{
if(map[x][y]==k+) return -;
if(map[x][y]>) continue;
if((t[x][y]&(<<k))==)
{
if(p!=-) return -;
p=x;
}
}
if(p!=-) return p;
return -;
} inline void grid(int r,int c,int k,int &x,int &y)
//以(r,c)为左上角的16宫格,数字k+1,(x,y)为唯一可填坐标[
{
x=-;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
{
if(map[r+i][c+j]==k+) {x=-; return ;}
if(map[r+i][c+j]>) continue;
if((t[r+i][c+j]&(<<k))==)
{
if(x!=-) {x=-; return ;}
x=i,y=j;
}
}
} inline int count_1(unsigned short x) {
int tmp();
while(x) {
if(x&) tmp++;
x>>=;
}
return tmp;
} bool search()
{
if(filled==) return true;
//先看是否有能确定的格子
for(res x= ; x< ; x++)
for(res y= ; y< ; y++)
{
if(map[x][y]>) continue;
int k=count_zero(t[x][y]);
if(k!=-) my_fill(x,y,k+);
}
for(res x= ; x< ; x++)
for(res k= ; k< ; k++)
{
int y=col(x,k);
if(y==-) return false;
if(y!=-) my_fill(x,y,k+);
}
for(res y= ; y< ; y++)
for(res k= ; k< ; k++)
{
int x=row(y,k);
if(x==-) return false;
if(x!=-) my_fill(x,y,k+);
}
for(res r= ; r< ; r+=)
for(res c= ; c< ; c+=)
for(res k= ; k< ; k++)
{
int x,y;
grid(r,c,k,x,y);
if(x==-) return false;
if(x!=-) my_fill(r+x,c+y,k+);
}
if(filled==) return true;
int t_filled(filled);
int t_map[N][N];
unsigned short t_t[N][N];
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
t_map[i][j]=map[i][j],
t_t[i][j]=t[i][j];
//找可能情况最少的格子来枚举
int mx,my,mn=;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
{
if(map[i][j]>) continue;
int r=-count_1(t[i][j]);
//未确定的
if(r<mn)
{
mn=r; mx=i; my=j;
}
}
for(res k= ; k< ; k++)
if((t[mx][my]&<<k)==)
{
my_fill(mx,my,k+);
if(search()) return true;
filled=t_filled;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
map[i][j]=t_map[i][j],
t[i][j]=t_t[i][j];
}
return false;
} char ar[N];
int main()
{
while()
{
filled=;
memset(map,,sizeof(map)); memset(t,,sizeof(t));
for(int i= ; i< ; i++)
{
if(scanf("%s",ar)==EOF) return ;
for(int j= ; j< ; j++)
if(ar[j]!='-') my_fill(i,j,ar[j]-'A'+);
}
search();
for(res i= ; i< ; i++)
{
for(res j= ; j< ; j++) printf("%c",map[i][j]+'A'-);
puts("");
}
puts("");
}
return ;
}

POJ3076 Sudoku的更多相关文章

  1. POJ3076 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 学完这个之后,再 ...

  2. 【转】Dancing Links题集

    转自:http://blog.csdn.net/shahdza/article/details/7986037 POJ3740 Easy Finding [精确覆盖基础题]HUST1017 Exact ...

  3. dancing links 题集转自夏天的风

    POJ3740     Easy Finding [精确覆盖基础题] HUST1017    Exact cover [精确覆盖基础] HDOJ3663 Power Stations [精确覆盖] Z ...

  4. Sudoku(POJ2676/3074)

    Sudoku is one of the metaphysical techniques. If you understand the essence of it, you will have the ...

  5. Leetcode 笔记 36 - Sudoku Solver

    题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...

  6. [LeetCode] Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  7. [LeetCode] Valid Sudoku 验证数独

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  8. LeetCode 36 Valid Sudoku

    Problem: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board ...

  9. 【leetcode】Valid Sudoku

    题目简述: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board cou ...

随机推荐

  1. HDFS Hbase

    Hbase:Hbase是Hadoop的数据库,是bigtable的实现,基于HDFSHDFS:文件系统,是gfs的实现 Hive,Hbase,HDFS等之间的关系Hive:Hive不支持更改数据的操作 ...

  2. Luogu 4705 玩游戏

    看见这个题依稀想起了$5$月月赛时候的事情,到现在仍然它感觉非常神仙. 游戏$k$次价值的期望答案 $$ans_k = \frac{1}{nm}\sum_{i = 1}^{n}\sum_{j = 1} ...

  3. [Training Video - 6] [File Reading] [Java] Create and Write Excel File Using Apache POI API

    package com.file.properties; import java.io.File; import java.io.FileNotFoundException; import java. ...

  4. Oracle Nested table、Record

    1.如何在PL/SQL中创建和使用Nested table;2.如何在PL/SQL中创建和使用Record; 1.如何在PL/SQL中创建和使用Nested table DECLARE /**创建一个 ...

  5. rest-framework-----url控制

    一:自定义路由(原始方式) from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^books/ ...

  6. kcp源码segment头文件各字段含义

    conv conv为一个表示会话编号的整数,和tcp的 conv一样,通信双// 方需保证 conv相同,相互的数据包才能够被认可 cmd             cmd用来区分分片的作用.IKCP_ ...

  7. Logback configuration

    官方指导 http://logback.qos.ch/manual/configuration.html 规则 ch.qos.logback.core.joran.JoranConfiguratorB ...

  8. jquery cookie用法

    jquery cookie用法(获取cookie值,删除cookie) cookie在jquery中有指定的cookie操作类,下面我先来介绍我们在使用cookie操作类时的一些问题,然后介绍正确的使 ...

  9. Codeforces 691E Xor-sequences(矩阵快速幂)

    You are given n integers a1,  a2,  ...,  an. A sequence of integers x1,  x2,  ...,  xk is called a & ...

  10. Java菜鸟之java基础语法,运算符(三)

    赋值运算符 (一)JAVA种的赋值运算符 = ,代表代表的等于,一般的形式是  左边变量名称   =     右边的需要赋的指或者表达式,如果左侧的变量类型级别比较高,就把右侧的数据转换成左侧相同的高 ...