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 ...
随机推荐
- Linux备份
Eking<longpeisky@vip.qq.com> 19:35:17 增量备份是针对于上一次备份(无论是哪种备份):备份上一次备份后,所有发生变化的文件. (增量备份过程中,只备份 ...
- [Javascript] Call Stack
Every time when a function run it will be push into the call stack and put on the top, you can thin ...
- hdu4000 && hrbust1625
ikki的数字 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 22(12 users) Total Accepted: 9(8 use ...
- 【Android 应用开发】 ActionBar 样式详解 -- 样式 主题 简介 Actionbar 的 icon logo 标题 菜单样式修改
作者 : 万境绝尘 (octopus_truth@163.com) 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/3926916 ...
- 并行计算基础&编程模型与工具
在当前计算机应用中,对快速并行计算的需求是广泛的,归纳起来,主要有三种类型的应用需求: 计算密集(Computer-Intensive)型应用,如大型科学project计算与数值模拟: 数据密集(Da ...
- Codeforces Round #260 (Div. 2)A. Laptops
A. Laptops time limit per test 1 second memory limit per test 256 megabytes input standard input out ...
- VMware SphereESXi上传系统镜像
VMware SphereESXi上传系统镜像 打开右侧[摘要]选项卡 在[资源]中选择存储器中的存储,右键[浏览数据库存储] 选择工具栏[创建文件夹]图标,命名后保存 这样随后找到存储设备,浏览刚才 ...
- SQL SERVER数据库服务操作
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Android异步请求
class MyTask_SendMessage extends AsyncTask<String, Void, String> { @Override protected void on ...
- Java 日期与字符串的转换
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public cl ...