Sample Input

4 2
.###
#...
.#..
#.#.
3 1
.#.
.#.
.#.

Sample Output

4
-1

题意:给一个n*n的图,每次最多能跳k个格子,只能向南(下)或东(右)跳,不能落在‘#’上,求从右上角到左下角的最短时间。

题解:看到图、最短时间第一个反应就是BFS,可惜超时,候来优化了几次,勉强卡时间过了,别人貌似有DP过的,以后抽时间补上这种方法。

先说BFS吧,假设点为(i,j)那么标记的时候会把(i+1,j),(i+2,j)...(i+k,j),(i,j+1),(i,j+2)...(i,j+k)标记,而接下来会走如果(i+1,j),则会标记(i+2,j),(i+3,j)...(i+k+1,j),这样会有重复标记,导致时间复杂度上升。

通过观察不难发现,每次新标记的都是后面几个,所以我们可以倒着标记,当发现这个点被标记时就结束就好。

不过这样需要考虑方向问题,即是横向走的时候被标记了,还是纵向走的时候被标记了,具体看代码。

//如果标记过就结束循环
1111
1000
1111
1111
//就会出现类似这样的情况,原因是第三行横向标记过,导致二三四列在标记的时候碰到第三行就停止了。
//只是举个例子,这不是代码实际标记情况。

附上代码

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue> using namespace std;
const int maxn = 2050; struct node
{
int x,y,step;
}; int f[maxn][maxn],n,k;
char s[maxn][maxn]; void BFS()
{
int i,MIN,dx,dy,m;
queue<node> q;
node t1,t2;
memset(f,0,sizeof(f));
//关于标记,1 代表从上方跳过来,2 代表从左边跳过来,3代表上方,左边都到过这个点。
f[0][0] = 3;
t1.x = t1.y = t1.step = 0;
q.push(t1);
MIN = -1;
while(!q.empty())
{
t1 = q.front();
q.pop();
if(t1.x==n-1&&t1.y==n-1)//结束标志
{
MIN = t1.step;
break;
}
//纵向标记。
if(t1.x+k>=n)//如果最长距离跳出了边界,那么把距离控制在边界内。
m = n - t1.x - 1;
else
m = k;
for(i=m;i>=1;i--)
{
dx = t1.x + i;
dy = t1.y;
if(f[dx][dy]==1||f[dx][dy]==3)
break;
if(s[dx][dy]!='#')
{
if(!f[dx][dy])
f[dx][dy] = 1;
else
f[dx][dy] = 3;
t2.x = dx;
t2.y = dy;
t2.step = t1.step + 1;
q.push(t2);
}
}
//横向标记
if(t1.y+k>=n)
m = n - t1.y - 1;
else
m = k;
for(i=m;i>=1;i--)
{
dx = t1.x;
dy = t1.y + i;
if(f[dx][dy]==2||f[dx][dy]==3)
break;
if(s[dx][dy]!='#')
{
if(!f[dx][dy])
f[dx][dy] = 2;
else
f[dx][dy] = 3;
t2.x = dx;
t2.y = dy;
t2.step = t1.step + 1;
q.push(t2);
}
}
}
printf("%d\n",MIN);
} int main()
{
int i;
scanf("%d%d",&n,&k);
for(i=0;i<n;i++)
scanf("%s",s[i]);
BFS();
return 0;
}

最新文章

  1. Linux命令(21)查看文件的行数
  2. PPTP VPN 一键安装包(图文,OpenVZ适用)[zz]
  3. Windows Store App 应用程序存储空间
  4. Comet技术浅论
  5. 排序之希尔排序(shell sort)
  6. Android AlarmManager报警的实现
  7. ubuntu安装jdk的两种方法
  8. Solr DateRangeField
  9. Struts2之配置文件中Action的详细配置
  10. [Swift]LeetCode719. 找出第 k 小的距离对 | Find K-th Smallest Pair Distance
  11. 【原】Java学习笔记011 - 数组
  12. 2019.04.21 python核心特征
  13. 面试小记---java基础知识
  14. HP-JavaUtil: xls 操作类
  15. webstorm快捷键 webstorm keymap内置快捷键英文翻译、中英对照说明
  16. PREV-2_蓝桥杯_打印十字图
  17. OAuth 2.0授权之授权码授权
  18. 破产姐妹第六季/全集2 Broke Girls迅雷下载
  19. Java实现策略模式的简单应用
  20. Selenium_RC环境配置

热门文章

  1. C# 多线程操作之异步委托
  2. linux 调整系统时区
  3. iframe调用父页面各种方法
  4. 解释器模式(Interpreter、Context、Expression)
  5. Docker安装elasticsearch-head监控ES步骤 - gmijie的专栏 - CSDN博客
  6. 依赖注入的方式(DI)
  7. 集训队日常训练20180513-DIV2
  8. javaScript中的事件对象event是怎样
  9. 【Ruby】与ruby相关的内容
  10. Django与HTML业务基本结合