POJ 3076
DLX算法,刚接触,是关于精确覆盖的,白书上有算法介绍。
代码模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std; char puzzle[20][20];
const int SLOT=0;
const int ROW=1;
const int COL=2;
const int SUB=3;
const int maxn=1300;
const int maxnode=256*16*4;
const int maxr=256*16*4; struct DLX
{
int n , sz; // 行数,节点总数
int S[maxn]; // 各列节点总数
int row[maxnode],col[maxnode]; // 各节点行列编号
int L[maxnode],R[maxnode],U[maxnode],D[maxnode]; // 十字链表 int ansd,ans[maxn]; // 解 void init(int n )
{
this->n = n ;
for(int i = 0 ; i <= n; i++ )
{
U[i] = i ;
D[i] = i ;
L[i] = i - 1;
R[i] = i + 1;
}
R[n] = 0 ;
L[0] = n;
sz = n + 1 ;
memset(S,0,sizeof(S));
}
void addRow(int r,vector<int> c1)
{
int first = sz;
for(int i = 0 ; i < c1.size(); i++ ){
int c = c1[i];
L[sz] = sz - 1 ; R[sz] = sz + 1 ; D[sz] = c ; U[sz] = U[c];
D[U[c]] = sz; U[c] = sz;
row[sz] = r; col[sz] = c;
S[c] ++ ; sz ++ ;
}
R[sz - 1] = first ; L[first] = sz - 1;
}
// 顺着链表A,遍历除s外的其他元素
#define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i]) void remove(int c){
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {U[D[j]] = U[j];D[U[j]] = D[j];--S[col[j]];}
}
void restore(int c){
FOR(i,U,c)
FOR(j,L,i) {++S[col[j]];U[D[j]] = j;D[U[j]] = j; }
L[R[c]] = c;
R[L[c]] = c;
}
bool dfs(int d){
if(R[0] == 0 ){
ansd = d;
return true;
}
// 找S最小的列c
int c = R[0] ;
FOR(i,R,0) if(S[i] < S[c]) c = i; remove(c);
FOR(i,D,c){
ans[d] = row[i];
FOR(j,R,i) remove(col[j]);
if(dfs(d + 1)) return true;
FOR(j,L,i) restore(col[j]);
}
restore(c); return false;
}
bool solve(vector<int> & v){
v.clear();
if(!dfs(0)) return false;
for(int i = 0 ; i< ansd ;i ++ ) v.push_back(ans[i]);
return true;
}
};
DLX slover; int encode(int a,int b,int c){
return a*256+b*16+c+1;
} void decode(int code,int &a,int &b,int &c){
code--;
c=code%16; code/=16;
b=code%16; code/=16;
a=code;
} bool read(){
for(int i=0;i<16;i++){
if(scanf("%s",puzzle[i])!=1) return false;
}
return true;
} int main(){
int kase=0;
while(read()){
if(++kase!=1) printf("\n");
slover.init(1024);
for(int r=0;r<16;r++){
for(int c=0;c<16;c++){
for(int v=0;v<16;v++){
if(puzzle[r][c]=='-'||puzzle[r][c]=='A'+v){
vector<int> columns;
columns.clear();
columns.push_back(encode(SLOT,r,c));
columns.push_back(encode(ROW,r,v));
columns.push_back(encode(COL,c,v));
columns.push_back(encode(SUB,(r/4)*4+c/4,v));
slover.addRow(encode(r,c,v),columns);
}
}
}
}
vector<int>ans;
// cout<<"YES"<<endl;
ans.clear();
slover.solve(ans);
// cout<<"YES"<<endl;
for(int i=0;i<ans.size();i++){
int r,c,v;
decode(ans[i],r,c,v);
puzzle[r][c]='A'+v;
}
for(int i=0;i<16;i++)
printf("%s\n",puzzle[i]);
}
return 0;
}
POJ 3076的更多相关文章
- (简单) 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
[题目链接] http://poj.org/problem?id=3076 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 [代码] #include <algorit ...
- POJ 3076 Sudoku DLX精确覆盖
DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 4416 Accepte ...
- POJ 3076 Sudoku
3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...
- POJ 3076 / ZOJ 3122 Sudoku(DLX)
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- POJ 3076 Sudoku (dancing links)
题目大意: 16*16的数独. 思路分析: 多说无益. 想说的就是dancing links 的行是依照 第一行第一列填 1 第一行第二列填 2 -- 第一行第十五列填15 第一行第二列填 1 -- ...
- Sudoku POJ - 3076
Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 5769 Accepted: 2684 Descripti ...
- Sudoku POJ - 3076 (dfs+剪枝)
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- POJ 3076 SUKODU [Dangcing Links DLX精准覆盖]
和3074仅仅有数目的不同,3074是9×9.本来想直接用3074的.然后MLE,,,就差那么20M的空间,,. 从这里学习到了解法: http://www.cnblogs.com/ylfdrib/a ...
随机推荐
- selenium3 + python - select定位
一.Select模块(index) 1.导入Select模块.直接根据属性或索引定位 2.先要导入select方法:from selenium.webdriver.support.se ...
- 【钓起来的tips系列】
一.求n的阶乘: #include<bits/stdc++.h> using namespace std; int n; int jc(int k) { ); )*k; } /*int j ...
- 【LuoguP2210 USACO】 Haywire
这种答案跟序列排列顺序有关的,n比较小的(稍微大一点的也可以),求最优解的,一般都可以随机化过 随机化不一定是模拟退火或是什么遗传蚁群 哪怕只是直接随机化一个序列,只要你随机的次数够多,它都能找到正解 ...
- 分别使用Hadoop和Spark实现TopN(1)——唯一键
0.简介 TopN算法是一个经典的算法,由于每个map都只是实现了本地的TopN算法,而假设map有M个,在归约的阶段只有M x N个,这个结果是可以接受的并不会造成性能瓶颈. 这个TopN算法在ma ...
- JS排序之快速排序
JS排序之快速排序 一个数组中的数据,选择索引为(2/数组长度)的那个数据作为基数,数组中的其他数据与它对比,比它数值小的放在做数组,比它数值大的放在右数组,最后组合 左数组+基数+右数组,其中,左数 ...
- ThreadPoolExecutor理解
ThreadPoolExecutor组成 ThreadPoolExecutor的核心构造函数: public ThreadPoolExecutor(int corePoolSize, int maxi ...
- 安装完MongoDB后尝试mongod -dbpath命令为什么会一直卡在连接端口?
1.现象如下 Linux Windows 2.原因 其实,这不是卡住了,而是告诉我们.数据库已经启动,而且这个东东还不能关掉,关掉意味着数据库也关了.一开始我也是傻逼逼的在那等了一天,哎.... 3. ...
- Spark on Yarn集群搭建
软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...
- dotnetnuke 中使用ado.net entityframework 如果在程序中动态调用系统的连接字符串信息
1,打开如下图的Model1.Context.cs文件 2,找到 Base:(ConnString.conn)是我改的.默认生成的是"name=实体连接字符串" Connstrin ...
- DOM高级编程
前言:W3C规定的三类DOM标准接口(换图)Core DOM(核心DOM),适用于各种结构化文档:XML DOM(Java OOP学过),专用于XML文档:HTML DOM,专用于HTML文档,下面了 ...