输入要给n*m的棋盘  均小于10   某些格子有标记  用最少的皇后  辐射到所有的标记

限时 6666ms

用IDA*    时间6000  尴尬。

#include<bits/stdc++.h>
using namespace std;
#define N 10
int n,m;
int mp[N][N];
int cnt;
int visn[N];
int vism[N];
int visx[*N]; bool dfs(int d,int maxx)
{
if(cnt==)return true;
if(d==maxx)return false;
if( (maxx-d)*( *n+m- ) <cnt )return false;//毫无用处。。 int oldmap[N][N];//一定要开到里面 一开始开到外面错了!
memcpy(oldmap,mp,sizeof mp);
int oldcnt=cnt;
for(int i=;i<=n;i++)
if(!visn[i])
for(int j=;j<=m;j++)
if(!vism[j])
{
visn[i]=vism[j]=visx[i+j]=;
for(int k=;k<=n;k++)
if(mp[k][j])cnt--,mp[k][j]=;
for(int k=;k<=m;k++)
if(mp[i][k])cnt--,mp[i][k]=;
for(int k=;k<=n;k++)
for(int s=;s<=m;s++)
{
if( (s-k)==(j-i)||(s+k)==(i+j) )
if(mp[k][s]) mp[k][s]=,cnt--;
}
if(cnt!=oldcnt)
if(dfs(d+,maxx))return true;
memcpy(mp,oldmap,sizeof mp);
cnt=oldcnt;
visn[i]=vism[j]=;
}
return false;
} int solve()
{
if(cnt==)return ;
for(int maxx=;;maxx++){
memset(visn,,sizeof visn);
memset(vism,,sizeof vism);
if(dfs(,maxx) )return maxx;
}
} int main()
{
int cas=;
while(scanf("%d",&n),n)
{ cnt=;
scanf("%d",&m);getchar();
char ch;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
scanf("%c",&ch);
if(ch=='X')mp[i][j]=,cnt++;
}
getchar();
}
printf("Case %d: %d\n",++cas,solve());
}
}

每次dfs都要扫面落子的四个方位实在太费时间 真的铁脑残

应该像八皇后问题那样  设置标记数组就好了!! 900ms

#include<bits/stdc++.h>
using namespace std;
#define N 10
int n,m;
int mp[N][N];
int cnt;
int visn[N];
int vism[N];
int visx[*N];
int visy[*N]; bool judge()
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(mp[i][j]&&!visn[i]&&!vism[j]&&!visx[i+j]&&!visy[i-j+])return false; return true; } bool dfs(int d,int maxx)
{
if(judge())return true;
if(d==maxx)return false; for(int i=;i<=n;i++)
if(!visn[i])
for(int j=;j<=m;j++)
if(!vism[j])
{
visn[i]=vism[j]=;
int a=visx[i+j], b=visy[i-j+];
visx[i+j]=visy[i-j+]=; if(dfs(d+,maxx))return true;
visn[i]=vism[j]=;
visx[i+j]=a;visy[i-j+]=b;
}
return false;
} int solve()
{
if(cnt==)return ;
for(int maxx=;;maxx++){
memset(visn,,sizeof visn);
memset(vism,,sizeof vism);
memset(visx,,sizeof visx);
memset(visy,,sizeof visy);
if(dfs(,maxx) )return maxx;
}
} int main()
{
int cas=;
while(scanf("%d",&n),n)
{ cnt=;
scanf("%d",&m);getchar();
char ch;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
scanf("%c",&ch);
if(ch=='X')mp[i][j]=,cnt++;
else mp[i][j]=;
}
getchar();
}
printf("Case %d: %d\n",++cas,solve());
}
}

对行数进行优化  使行数升序:90ms 可以保证没有重复 !!!  上面那个代码有很多重复

#include<bits/stdc++.h>
using namespace std;
#define N 10
#define maxn 12
int n,m;
int mp[N][N];
int cnt;
int visn[N];
int vism[N];
int visx[*N];
int visy[*N];
int maxx;
bool judge()
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(mp[i][j]&&!visn[i]&&!vism[j]&&!visx[i+j]&&!visy[i-j+])return false;
return true;
} bool dfs(int d,int raw)
{
if(judge())return true;
if(d==maxx)return false; for(int i=raw;i<=n;i++)
for(int j=;j<=m;j++)
{
int c=visn[i],d1=vism[j],a=visx[i+j], b=visy[i-j+]; visx[i+j]=visy[i-j+]=visn[i]=vism[j]=; if(dfs(d+,i+))return true; visn[i]=c,vism[j]=d1;
visx[i+j]=a;visy[i-j+]=b;
}
return false;
} int solve()
{
for( maxx=;;maxx++){
memset(visn,,sizeof visn);
memset(vism,,sizeof vism);
memset(visx,,sizeof visx);
memset(visy,,sizeof visy);
if(dfs(,) )return maxx;
}
} int main()
{
int cas=;
while(scanf("%d",&n),n)
{
scanf("%d",&m);getchar();
char ch;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
scanf("%c",&ch);
if(ch=='X')mp[i][j]=;
else mp[i][j]=;
}
getchar();
}
printf("Case %d: %d\n",++cas,solve());
}
}

7-10 守卫棋盘 uva11214的更多相关文章

  1. UVA - 11214 Guarding the Chessboard(守卫棋盘)(迭代加深搜索)

    题意:输入一个n*m棋盘(n,m<10),某些格子有标记.用最少的皇后守卫(即占据或者攻击)所有带标记的格子. 分析:因为不知道放几个皇后可以守卫所有带标记的格子,即回溯法求解时解答树的深度没有 ...

  2. UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)

    暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的. 1.最裸的暴搜 6.420s,差点超时 2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放 0.400s # ...

  3. UVA-11214 IDA*

    利用迭代加深搜索,枚举需要的皇后数量,进行搜索. 对于10 * 10 的棋盘,最多需要5个皇后就能攻击整个棋盘,当0~4个皇后都不能搜索成功,那么5就不用搜索,直接打印. AC代码: #include ...

  4. [kuangbin带你飞]专题一 简单搜索 棋盘问题

    题来:链接https://vjudge.net/problem/OpenJ_Bailian-132 J - 棋盘问题 1.题目: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别. ...

  5. SGU 220.Little Bishops(DP)

    题意: 给一个n*n(n<=10)的棋盘,放上k个主教(斜走),求能放置的种类总数. Solution: 一眼看上去感觉是状压DP,发现状态太多,没办法存下来... 下面是一个十分巧妙的处理: ...

  6. C语言数据结构----递归的应用(八皇后问题的具体流程)

    本节主要讲八皇后问题的基本规则和递归回溯算法的实现以及具体的代码实现和代码分析. 转载请注明出处.http://write.blog.csdn.net/postedit/10813257 一.八皇后问 ...

  7. HTML页面过渡效果大全

    IE要求: 在IE5.5及以上版本的浏览器中.启用网页过渡效果 默认情况下都已经启用了,如果需要手动启用则只需在Internet选项中: Advanced(高级) - Browsing(浏览) - E ...

  8. 界面编程之QT的文件操作20180729

    /*******************************************************************************************/ 一.QT文件 ...

  9. [HAOI2015]数组游戏

    题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...

随机推荐

  1. redis sentinel集群

    ip分布情况: sentinel-1/redis 主 10.11.11.5 sentinel-2/redis 从 10.11.11.7 sentinel-3/redis 从 10.11.11.8 ha ...

  2. BFS:八数码问题

    #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> ...

  3. 接口测试Case之面向页面对象编写及规范

    一.什么是页面对象化 主要提倡的思想是:万物皆对象,即把一个Page看成一个对象,来进行接口自动化Case的编写,不要闲扯,直接讲怎么个操作法呢? 二.有什么优势? 2.1 Case层次清晰,便于管理 ...

  4. c# 判断一个数是不是质数或者求一个数的公约数的算法

    一个数是不是质数,就是判断一个数除了1和它本身还有没有其他的约数,如果有则是合数,否则是质数.其实本质都是求公约数. 求公约数是什么思路呢,就是找比它小的数不断尝试,能被整除则是其约数,否则继续尝试, ...

  5. redis内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...

  6. 详细讲解安全升级MySQL的方法

    MySQL升级是非常必要的. 我们在Percona Support上列出了关于MySQL升级最佳实践的各种问题.这篇文章推荐了一些不同情况下升级MySQL的方法. 为什么MySQL升级是必须的? 原因 ...

  7. noip2012 P1081 开车旅行

    小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i 和城市 j ...

  8. BFS 两个重要性质

    对于进行广度优先搜索的队列中,应该始终满足两个性质:   性质1:若队首为第i层拓展到的节点,则队列中最多只能存在第i层和第i+1层的节点,不可能出现3层节点.   性质2:队列中的元素会严格按照层数 ...

  9. 25、LinkedList特有方法

    LinkedList特有方法 public void addFirst(E e)及addLast(E e) public E getFirst()及getLast() public E removeF ...

  10. shell脚本-监控及邮件提醒

    首先写一个邮件提醒python文件 #!/usr/bin/python # -*- coding: UTF-8 -*- import sys import smtplib import email.m ...