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格子上的子. 不能操作者负. 思路: 将“某个格 ...
随机推荐
- 洛谷P2766 最长递增子序列问题
https://www.luogu.org/problemnew/show/P2766 注:题目描述有误,本题求的是最长不下降子序列 方案无限多时输出 n 网络流求方案数,长见识了 第一问: DP 同 ...
- SHA-1(安全哈希算法实现)
如题,不知道sha-1的自己百度吧. #include <iostream> #include <vector> //定义vector数组 #include <strin ...
- R5—字符串处理/正则表达式
R通常被用来进行数值计算比较多,字符串处理相对较少,而且关于字符串的函数也不多,用得多的就是substr.strsplit.paste.regexpr这几个了.实际上R关于字符串处理的功能是非常强大的 ...
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
- 【转】线程间操作无效: 从不是创建控件“textBox2” 的线程访问它。
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- 【文件上传】文件上传的form表单提交方式和ajax异步上传方式对比
一.html 表单代码 …… <input type="file" class="file_one" name="offenderExcelFi ...
- 【译】第六篇 SQL Server代理深入作业步骤工作流
本篇文章是SQL Server代理系列的第六篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.每个作业步骤在技术 ...
- UNIX环境高级编程 第2章 UNIX标准及实现
在过去的将近25年时间,人们为了UNIX的标准化做出了种种努力,这使得程序在不同版本的UNIX系统之间的移植相当容易. ISO C 1989年,C语言首个标准得到批准,其为C89.次年,一个带有小改动 ...
- 10 Useeful Tips for Writing Effective Bash Scripts in Linux
1.Always Use Comments in Scripts2.Make a Scripts exit When Fails Sometimes bash may continue to e ...
- java创建并配置多module的maven项目
1 使用idea创建(推荐) 这篇博客写的特别好,很详细: https://blog.csdn.net/sinat_30160727/article/details/78109769 2 使用ecli ...