Spoj1771-Yet Another N-Queen Problem(精确覆盖)
Description
After solving Solution to the n Queens Puzzle by constructing, LoadingTime wants to solve a harder version of the N-Queen Problem. Some queens have been set on particular locations on the board in this problem. Can you help him??
Input
The input contains multiple test cases. Every line begins with an integer N (N<=50), then N integers followed, representing the column number of the queen in each rows. If the number is 0, it means no queen has been set on this row. You can assume there is at least one solution.
Output
For each test case, print a line consists of N numbers separated by spaces, representing the column number of the queen in each row. If there are more than one answer, print any one of them.
Example
Input:
4 0 0 0 0
8 2 0 0 0 4 0 0 0 Output:
2 4 1 3
2 6 1 7 4 8 3 5
题意:N皇后问题,但是棋盘已经有一些皇后,然后问如何选择皇后的位置使得他们互不攻击,N<=50
解析:N这么大,显然不可能爆搜,这里用到的是精确覆盖DLX算法,行表示每个点,DLX的列对应棋盘的行,列和两个方向的斜对角。
搜到N步就可以了,考虑行就好了,不用考虑斜对角什么的。
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int INF=1e9+;
const int ms=*;
const int maxn=ms*;
int N,ans[],res[];//ans存储第几个选择的编号,res保存第几行答案是第几列
struct DLX
{
int n,id;
int L[maxn],R[maxn],U[maxn],D[maxn];
int C[maxn],S[maxn],loc[maxn][];
int H[ms];
void init(int nn=) //传列长
{
n=nn;
for(int i=;i<=n;i++) U[i]=D[i]=i,L[i]=i-,R[i]=i+;
L[]=n; R[n]=;
id=n;
memset(S,,sizeof(S));
memset(H,-,sizeof(H));
}
void Link(int x,int y)
{
++id;
D[id]=y; U[id]=U[y];
D[U[y]]=id; U[y]=id;
loc[id][]=x,loc[id][]=y;
C[id]=y; S[y]++;
if(H[x]==-) H[x]=L[id]=R[id]=id;
else
{
int a=H[x];
int b=R[a];
L[id]=a; R[a]=id;
R[id]=b; L[b]=id;
H[x]=id;
}
}
void Remove(int c)
{
L[R[c]]=L[c];
R[L[c]]=R[c];
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
{
U[D[j]]=U[j];
D[U[j]]=D[j];
S[C[j]]--;
}
}
void Resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
for(int j=R[i];j!=i;j=R[j])
{
S[C[j]]++;
U[D[j]]=j;
D[U[j]]=j;
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int step)
{
if(step>=N) return true;
if(R[]==) return false;
int Min=INF,c=-;
for(int i=R[];i;i=R[i])
{
if(i>N) break;
if(Min>S[i]){ Min=S[i]; c=i; }
}
if(c==-) return false;
Remove(c);
for(int i=D[c];i!=c;i=D[i])
{
ans[step]=loc[i][];
for(int j=R[i];j!=i;j=R[j]) Remove(C[j]);
if(dfs(step+)) return true;
for(int j=L[i];j!=i;j=L[j]) Resume(C[j]);
}
Resume(c);
return false;
}
}dlx;
bool vis[*];
int main()
{
while(scanf("%d",&N)!=EOF)
{
dlx.init(N*-);
memset(vis,false,sizeof(vis));
int y;
for(int x=;x<=N;x++)
{
scanf("%d",&y);
if(y==) continue;
int a=x,b=N+y,c=*N+N+x-y,d=*N+x+y-; //对应的行列斜对角编号
vis[a]=vis[b]=vis[c]=vis[d]=true; //标记
int t=(x-)*N+y-;
dlx.Link(t,a); //连接
dlx.Link(t,b);
dlx.Link(t,c);
dlx.Link(t,d);
}
for(int x=;x<=N;x++)
for(int y=;y<=N;y++)
{
int a=x,b=N+y,c=*N+N+x-y,d=*N+x+y-;
if(vis[a]||vis[b]||vis[c]||vis[d]) continue; //有被占据不考虑
int t=(x-)*N+y-;
dlx.Link(t,a);
dlx.Link(t,b);
dlx.Link(t,c);
dlx.Link(t,d);
}
if(!dlx.dfs()) printf("No answer find\n");
else
{
for(int i=;i<N;i++) res[ans[i]/N]=ans[i]%N;
for(int i=;i<N;i++) printf("%d%c",res[i]+,i==N-?'\n':' ');
}
}
return ;
}
Spoj1771-Yet Another N-Queen Problem(精确覆盖)的更多相关文章
- [DLX精确覆盖] hdu 1603 A Puzzling Problem
题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个 ...
- 【转】DLX 精确覆盖 重复覆盖
问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0.如果G[i][j]==1则说明i行可以覆盖j列. Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列 ...
- Hdu3498-whosyourdaddy(精确覆盖模板题)
Problem Description sevenzero liked Warcraft very much, but he haven't practiced it for several year ...
- hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)
hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...
- DLX精确覆盖与重复覆盖模板题
hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...
- dancing link 精确覆盖 重复覆盖 (DLX)
申明:因为转载的没有给出转载链接,我就把他的链接附上,请尊重原创: http://www.cnblogs.com/-sunshine/p/3358922.html 如果谁知道原创链接 给一下,请尊重原 ...
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...
- HDU 3957 Street Fighter(搜索、DLX、重复覆盖+精确覆盖)
很久以前就看到的一个经典题,一直没做,今天拿来练手.街霸 给n<=25个角色,每个角色有 1 or 2 个版本(可以理解为普通版以及爆发版),每个角色版本可以KO掉若干人. 问最少选多少个角色( ...
- HDU 3111 Sudoku(精确覆盖)
数独问题,输入谜题,输出解 既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧...赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了... #include <cs ...
随机推荐
- 用Scrapy写一个爬虫
昨天用python谢了一个简单爬虫,抓取页面图片: 但实际用到的爬虫需要处理很多复杂的环境,也需要更加的智能,重复发明轮子的事情不能干, 再说python向来以爬虫作为其擅长的一个领域,想必有许多成熟 ...
- SQL - 删掉数据库
ALTER DATABASE [DB_NAME]SET OFFLINEWITH ROLLBACK IMMEDIATEGODROP DATABASE [DB_NAME]GO
- 与Jquery Mobile的第一次亲密接触
Jquery Mobile闻名已久,今天终于有亲密接触的机会. 通过动手写的demo,对它有了一个基本的认识: 自带的UI组件用起来简洁,方便:对旧版本的浏览器或移动设备能做到很好的优雅降级,而不影响 ...
- wcf简单的创建和运用
创建一个控制台应用程序,命名为wcftest,并在同一解决方案中添加一个wcf服务应用程序 在wcf项目中会自动生成Service1.svc服务程序文件和IService1.cs契约接口 IServi ...
- Button和ImageButton
Button----button ImageButton----图片button 共同拥有特征: 都能够作为一个button产生点击事件 不同点 1. Button有text的属性.ImageButt ...
- HeadFirst设计模式 之 C++实现(二):Observer(观察者模式)
观察者模式是最经常使用的设计模式之中的一个,[对象之间多对一的依赖关系,当一个对象发生变化时,其会通知全部依赖它的对象].拿订阅报纸和发行报社打例如,报社採集到news制作新的报纸,派送给订阅的客户. ...
- Javascript高级程序设计读书笔记(第六章)
第6章 面向对象的程序设计 6.2 创建对象 创建某个类的实例,必须使用new操作符调用构造函数会经历以下四个步骤: 创建一个新对象: 将构造函数的作用域赋给新对象: 执行构造函数中的代码: 返回新 ...
- Linux基础知识笔记
1.case的命令格式 #!/bin/sh echo "please input number 1 to 3" read number case $number in ) e ...
- js获取浏览器滚动条距离顶端的距离
最近在做项目的时候遇到需要用js获取滚动条距离窗口顶端的距离和js获取浏览器可视化窗口的大小,在这儿做一个整理保存: 一.jQuery获取的相关方法 jquery 获取滚动条高度 获取浏览器显示 ...
- document 例子
<!DOCTYPE html> <html> <head> <title></title> <script type="te ...