7-10 守卫棋盘 uva11214
输入要给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的更多相关文章
- UVA - 11214 Guarding the Chessboard(守卫棋盘)(迭代加深搜索)
题意:输入一个n*m棋盘(n,m<10),某些格子有标记.用最少的皇后守卫(即占据或者攻击)所有带标记的格子. 分析:因为不知道放几个皇后可以守卫所有带标记的格子,即回溯法求解时解答树的深度没有 ...
- UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的. 1.最裸的暴搜 6.420s,差点超时 2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放 0.400s # ...
- UVA-11214 IDA*
利用迭代加深搜索,枚举需要的皇后数量,进行搜索. 对于10 * 10 的棋盘,最多需要5个皇后就能攻击整个棋盘,当0~4个皇后都不能搜索成功,那么5就不用搜索,直接打印. AC代码: #include ...
- [kuangbin带你飞]专题一 简单搜索 棋盘问题
题来:链接https://vjudge.net/problem/OpenJ_Bailian-132 J - 棋盘问题 1.题目: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别. ...
- SGU 220.Little Bishops(DP)
题意: 给一个n*n(n<=10)的棋盘,放上k个主教(斜走),求能放置的种类总数. Solution: 一眼看上去感觉是状压DP,发现状态太多,没办法存下来... 下面是一个十分巧妙的处理: ...
- C语言数据结构----递归的应用(八皇后问题的具体流程)
本节主要讲八皇后问题的基本规则和递归回溯算法的实现以及具体的代码实现和代码分析. 转载请注明出处.http://write.blog.csdn.net/postedit/10813257 一.八皇后问 ...
- HTML页面过渡效果大全
IE要求: 在IE5.5及以上版本的浏览器中.启用网页过渡效果 默认情况下都已经启用了,如果需要手动启用则只需在Internet选项中: Advanced(高级) - Browsing(浏览) - E ...
- 界面编程之QT的文件操作20180729
/*******************************************************************************************/ 一.QT文件 ...
- [HAOI2015]数组游戏
题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...
随机推荐
- Java并发编程原理与实战三十一:Future&FutureTask 浅析
一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...
- 关于thinkpad安装win10操作系统
thinkpad预装的是win8或者win10,会有自己的分区方式是GPT,所以会出现两个引导分区. F2进入tinkpad的bios,F12进入启动选项 我们用pe进入后,用分区工具删除两个分区,然 ...
- 如何创建一个https的站点(超简单) 以及 IIS7.5绑定Https域名
1.申请免费1年的ssl证书(传送门:https://common-buy.aliyun.com/?spm=5176.2020520163.cas.29.N0xOPM&commodityCod ...
- 20155117王震宇实验四 Andoid开发基础实验报告
实验内容 1.Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)>第二十四章: - ...
- 跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险
跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险 跨站请求伪造(Cross-Site Request Forgery)或许是最令人难以理解的一种攻击方式了,但也正因如此,它的危险性也被人们所低估 ...
- ip_local_deliver && ip_local_deliver_finish
当ip包收上来,查路由,发现是发往本地的数据包时,会调用ip_local_deliver函数: ip_local_deliver中对ip分片进行重组,经过LOCAL_IN钩子点,然后调用ip_loca ...
- ### mysql系统结构_3_Mysql_Learning_Notes
mysql系统结构_3_Mysql_Learning_Notes 存储层,内存结构 全局(buferpool) 只分配一次 全局共享 连接/会话(session) 针对每个会话/线程分配 按需动态分配 ...
- poj1067
题意:有两堆石子,两人轮流取,每次可以取一堆中的任意个,或两堆中取相同多个.谁先取光所有堆谁赢.问先手能否获胜. 分析:威佐夫博弈,如果是奇异态则先手输,否则先手赢.直接套用公式判断是否为奇异态,设第 ...
- 在Mac上搭建ReactNative开发环境
1.安装Homebrew, Mac系统的包管理器,用于安装NodeJS和一些其他必需的工具软件. /usr/bin/ruby -e "$(curl -fsSL https://raw.g ...
- 使用gradle编译安卓APK
一.安装JDK 在安装Gradle之前需要先安装JDK,由于安装的是Gradle是4.4所以需要安装JDK1.8. 之前编译总是提示如下错误就是由于先安装的jdk1.7然后安装的1.8造成的,在Gra ...