看到这题,一下就想到了爆搜。(不过这题输入也是够坑的)

单纯的搜索肯定是会超时的,所以这里需要考虑一些剪枝。

我们令bin[i][j][k]为在第i行j列时,方向为k的最小镜子数,若当时的镜子数已大于或等于此记录,那么就不必要更新了

否则往该点的四个方向进行更新:

  • 方向相同

没必要放镜子了

  • 方向相反

不存在这种可能,忽略(否则你的镜子要怎么放呢?)

  • 其他

放一面镜子,更新方向

BFS代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100+10;
char Map[MAXN][MAXN];
int n,m;
int bx,by,ex,ey;
int dx[5]={0,0,1,0,-1};
int dy[5]={0,1,0,-1,0};
int ans=0x3f3f3f3f;
int bin[MAXN][MAXN][5];//剪枝用
struct Node
{
int x,y;
int cnt;
int dir;//表示的方向
/*
1:right
2:down
3:left
4:up
*/
};
inline int read()
{
int tot=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
tot=tot*10+c-'0';
c=getchar();
}
return tot;
}
inline void BFS()
{
queue<Node>q;
q.push((Node){bx,by,0,1});//推四种方向到队列中
q.push((Node){bx,by,0,2});
q.push((Node){bx,by,0,3});
q.push((Node){bx,by,0,4});
bin[bx][by][1]=bin[bx][by][2]=bin[bx][by][3]=bin[bx][by][4]=0;
while(q.size())
{
Node now=q.front();
//cout<<now.x<<" "<<now.y<<" "<<now.cnt<<" "<<now.dir<<endl;
q.pop();
if(now.cnt>=ans)continue;
if(now.x==ex&&now.y==ey)
{
ans=min(ans,now.cnt);//更新答案
continue;//注意:这里不能用break
}
for(int i=1;i<=4;i++)
{
int a=dx[i]+now.x,b=dy[i]+now.y;
if(a<1||b<1||a>n||b>m)continue;
if(now.cnt>=bin[a][b][i])continue;//没必要更新了
if(Map[a][b]=='*')continue;
if(now.dir==i)
{
q.push((Node){a,b,now.cnt,i});
bin[a][b][i]=now.cnt;//更新最小值
}
else
{
if(now.dir+i==4)continue;//这是方向相反时,看不懂的回去看一下各个数字代表的方向
q.push((Node){a,b,now.cnt+1,i});
bin[a][b][i]=now.cnt+1;//更新最小值
}
}
}
}
int main()
{
m=read();n=read();
memset(bin,0x3f3f3f3f,sizeof(bin));//赋初值
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>Map[i][j];
if(Map[i][j]=='C'&&!bx&&!by)bx=i,by=j;//寻找起点
else if(Map[i][j]=='C')ex=i,ey=j;//寻找终点
}
}
BFS();
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=1;k<=4;k++)cout<<bin[i][j][k]<<" ";
cout<<endl;
}
cout<<endl<<endl;
}*/
cout<<ans<<endl;
return 0;
}

最新文章

  1. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现
  2. tensorflow 一些好的blog链接和tensorflow gpu版本安装
  3. deepin linux字体渲染(转)
  4. CODE VS1008选数
  5. POJ3184 Ikki&#39;s Story I - Road Reconstruction(最大流)
  6. C#和JavaScript交互(asp.net前台和后台互调)总结 (转)
  7. 针对电信乌龙事件的深度测试: 广州电信错误将深圳地区189的号码在3G升级4G申请时从广州网厅发货,造成深圳用户收到4G卡后无法激活,深圳电信找不到订单
  8. MySQL: ON DUPLICATE KEY UPDATE 用法 避免重复插入数据
  9. calabash-android Win10 入门笔记
  10. 屌丝程序猿赚钱之道 之APP
  11. 记glide框架使用中所遇到的问题
  12. Elasticsearch 5.0 安装 Search Guard 5 插件 (五)
  13. VMware Ubuntu 安装
  14. python selenium 鼠标悬停
  15. 初识vue——语法初解
  16. C重新入门
  17. 题外话:Lua脚本语言存在的意义
  18. NEERC Southern Subregional 2011
  19. Double H5.0
  20. 1、算法介绍,lowB三人组,快速排序

热门文章

  1. Python 12---图形界面
  2. 生日礼物 HYSBZ - 1293 【单调队列】【求最短区间的长度,区间需要满足包含所有颜色种类】
  3. P5312 [Ynoi2011]D2T1
  4. 内存管理2-set方法的内存管理
  5. MySQL数据分析(7)-试着使用SQL
  6. [svn]查看,删除svn账号
  7. JavaWeb_(SpringMVC框架)SpringMVC&amp;Spring&amp;MyBatis整合
  8. Linux 时间同步 Chrony
  9. JMeter-jp@gc - PerfMon Metrics Collector-CPU监控工具的配置及使用(win版本)
  10. Python: 根据利润计算奖金