HDU 1728 逃离迷宫

这道题做的我想哭啊。。WA了将近十次了吧

一开始我用数组模拟的队列,后来和老大代码对拍,感觉改的是基本都一模一样了,还是WA

实在没有办法了,改用queue了

 

题目里的x是列y是行,和代码里的反过来的,要注意!

题目里面说在起点的时候无论朝哪个方向走都不算一次转弯,所以我们将方向和转弯次数都赋值为-1,这样就不用特殊处理了

入队条件,拓展后的转弯次数小于或等于vis数组中记录的最小转弯次数即可入队

输出结果,不要一搜到终点便急着输出,应为可能后面再一次搜到终点的时候转弯次数小于k

因此可以遍历完以后再输出,或者输出yes的时候加一个限制条件:转弯次数小于等于k

两种处理方法,第二种更快一点

 

这里先把数组WA掉的代码贴上,留着以后再找错。

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 struct Point
 8 {
 9     int x, y;
10     int di, times;
11 }qu[20000 + 10];
12 
13 const int MAX = 200;
14 char map[105][105];
15 int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
16 int row, col, vis[105][105];
17 int sx, sy, ex, ey, k;
18 int head, tail;
19 
20 bool islegal(int x, int y)
21 {
22     if(x>=0 && x<row && y>=0 && y<col && map[x][y]=='.')
23         return true;
24     return false;
25 }
26 
27 void BFS(void)
28 {
29     head = 0, tail = 1;
30     vis[sx][sy] = 0;
31     qu[0].x = sx, qu[0].y = sy;
32     qu[0].di = -1, qu[0].times = -1;
33     while(head < tail)
34     {
35         //if(qu[head].x==ex && qu[head].y==ey)
36             //{printf("yes\n");    return;}
37         for(int i = 0; i < 4; ++i)
38         {
39             int temp;
40             int xx = qu[head].x + dir[i][0];
41             int yy = qu[head].y + dir[i][1];
42             if(!islegal(xx, yy))    continue;
43             if(i != qu[head].di)
44                 temp = qu[head].times + 1;
45             else
46                 temp = qu[head].times;
47             if(temp > k)    continue;
48             if(temp <= vis[xx][yy])
49             {
50                 vis[xx][yy] = temp;
51                 qu[tail].x = xx, qu[tail].y = yy;
52                 qu[tail].di = i;
53                 qu[tail++].times = temp;
54             }
55         }
56         ++head;
57     }
58     if(vis[ex][ey] <= k)
59         printf("yes\n");
60     else
61         printf("no\n");
62 }
63 
64 int main(void)
65 {
66     #ifdef LOCAL
67         freopen("1728in.txt", "r", stdin);
68     #endif
69 
70     int T;
71     scanf("%d", &T);
72     while(T--)
73     {
74         scanf("%d%d", &row, &col);
75         getchar();
76         for(int i = 0; i < row; ++i)
77         {
78             for(int j = 0; j < col; ++j)
79             {
80                 scanf("%c", &map[i][j]);
81                 vis[i][j] = MAX;
82             }
83             getchar();
84         }
85         scanf("%d%d%d%d%d", &k, &sy, &sx, &ey, &ex);
86         --sx, --sy, --ex, --ey;
87         BFS();
88     }
89     return 0;
90 }
代码君

 

queue的AC代码:

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 using namespace std;
 7 
 8 struct Point
 9 {
10     int x, y;
11     int di, times;
12 }qu[20000 + 10];
13 
14 const int MAX = 200;
15 char map[105][105];
16 int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
17 int row, col, vis[105][105];
18 int sx, sy, ex, ey, k;
19 
20 bool islegal(int x, int y)
21 {
22     return(x>=0 && x<row && y>=0 && y<col && map[x][y]=='.');
23 }
24 
25 void BFS(void)
26 {
27     queue<Point> qu;
28     vis[sx][sy] = 0;
29     Point cur;
30     cur.x = sx, cur.y = sy;
31     cur.di = cur.times = -1;
32     qu.push(cur);
33     while(!qu.empty())
34     {
35         cur = qu.front();
36         qu.pop();
37         if(cur.x==ex&&cur.y==ey&&cur.times<=k)
38         {
39             printf("yes\n");
40             return;
41         }
42         for(int i = 0; i < 4; ++i)
43         {
44             Point next = cur;
45             next.x += dir[i][0];
46             next.y += dir[i][1];
47             if(!islegal(next.x, next.y))    continue;
48             if(i != cur.di)
49             {
50                 next.di = i;
51                 ++next.times;
52             }
53             if(next.times > k)    continue;
54             if(next.times <= vis[next.x][next.y])
55             {
56                 vis[next.x][next.y] = next.times;
57                 qu.push(next);
58             }
59         }
60     }
61     printf("no\n");
62 }
63 
64 int main(void)
65 {
66     #ifdef LOCAL
67         freopen("1728in.txt", "r", stdin);
68     #endif
69 
70     int T;
71     scanf("%d", &T);
72     while(T--)
73     {
74         scanf("%d%d", &row, &col);
75         getchar();
76         for(int i = 0; i < row; ++i)
77         {
78             for(int j = 0; j < col; ++j)
79             {
80                 scanf("%c", &map[i][j]);
81                 vis[i][j] = MAX;
82             }
83             getchar();
84         }
85         scanf("%d%d%d%d%d", &k, &sy, &sx, &ey, &ex);
86         --sx, --sy, --ex, --ey;
87         BFS();
88     }
89     return 0;
90 }
代码君

 

对比了一下别人的代码,才知道自己写的代码有多么挫。。

http://972169909-qq-com.iteye.com/blog/1244218

这里讲了两种方法,因为题目只是问能不能在转k个弯之内到达,而不是转的最小的弯,所以DFS也是能做的。30MS多点

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int MAX = 200;
 8 char map[105][105];
 9 int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
10 int row, col, vis[105][105];
11 int sx, sy, ex, ey, k;
12 bool flag; 
13 
14 bool islegal(int x, int y)
15 {
16     return(x>=0 && x<row && y>=0 && y<col && map[x][y]=='.');
17 }
18 
19 void DFS(int x, int y, int di)
20 {
21     if(x==ex && y==ey && vis[ex][ey]<=k)
22         {flag = true;   return;}
23     if(vis[x][y] > k)
24         return;
25     if(x!=ex && y!=ey && vis[x][y]==k)
26         return;
27     for(int i = 0; i < 4; ++i)
28     {
29         int tx = x + dir[i][0];
30         int ty = y + dir[i][1];
31         if(!islegal(tx, ty))
32             continue;
33         if(vis[tx][ty] < vis[x][y])
34             continue;
35         if(i!=di && vis[tx][ty] < vis[x][y]+1)
36             continue;
37         vis[tx][ty] = vis[x][y];
38         if(i != di)
39             ++vis[tx][ty];
40         DFS(tx, ty, i);
41         if(flag)
42             return;
43     }
44 }
45 
46 int main(void)
47 {
48     #ifdef LOCAL
49         freopen("1728in.txt", "r", stdin);
50     #endif
51 
52     int T;
53     scanf("%d", &T);
54     while(T--)
55     {
56         scanf("%d%d", &row, &col);
57         getchar();
58         for(int i = 0; i < row; ++i)
59         {
60             for(int j = 0; j < col; ++j)
61             {
62                 scanf("%c", &map[i][j]);
63                 vis[i][j] = MAX;
64             }
65             getchar();
66         }
67         scanf("%d%d%d%d%d", &k, &sy, &sx, &ey, &ex);
68         --sx, --sy, --ex, --ey;
69         vis[sx][sy] = -1;
70         flag = false;
71         DFS(sx, sy, -1);
72         if(flag)    printf("yes\n");
73         else    printf("no\n");
74     }
75     return 0;
76 }
代码君

 

下面重头戏来了,解法永远都是只有更好没有最好。博主讲了一个单方向优先扩展的广搜

把一般的广搜比作一个石子在起点激起一圈圈涟漪,单方向优先的就是向开车一样“横冲直撞”、直来直往

因为我们是要找转弯次数最小的,因此这样的搜索方式应该也能较快的找到符合条件的路径,运行时间15MS

感觉代码的有些小细节还没有理解透,等以后回过头来慢慢消化

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 using namespace std;
 7 
 8 struct Point
 9 {
10     int x, y;
11 }cur, next;
12 
13 const int MAX = 200;
14 char map[105][105];
15 int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
16 int row, col, vis[105][105];
17 int sx, sy, ex, ey, k;
18 
19 bool islegal(int x, int y)
20 {
21     return(x>=0 && x<row && y>=0 && y<col && map[x][y]=='.');
22 }
23 
24 void BFS(void)
25 {
26     queue<Point> qu;
27     vis[sx][sy] = -1;
28     Point cur;
29     cur.x = sx, cur.y = sy;
30     qu.push(cur);
31     while(!qu.empty())
32     {
33         cur = qu.front();
34         qu.pop();
35         if(cur.x==ex&&cur.y==ey&&vis[cur.x][cur.y]<=k)
36         {
37             printf("yes\n");
38             return;
39         }
40         for(int i = 0; i < 4; ++i)
41         {
42             next = cur;
43             next.x += dir[i][0];
44             next.y += dir[i][1];
45             while(islegal(next.x, next.y))
46             {
47                 if(vis[next.x][next.y] < vis[cur.x][cur.y] + 1)
48                     break;
49                 vis[next.x][next.y] = vis[cur.x][cur.y] + 1;
50                 if(vis[next.x][next.y] > k)
51                     break;
52                 if(vis[next.x][next.y] == k && next.x!=ex && next.y!=ey)
53                     break;
54                 qu.push(next);
55                 next.x += dir[i][0];
56                 next.y += dir[i][1];
57             }
58         }
59     }
60     printf("no\n");
61 }
62 
63 int main(void)
64 {
65     #ifdef LOCAL
66         freopen("1728in.txt", "r", stdin);
67     #endif
68 
69     int T;
70     scanf("%d", &T);
71     while(T--)
72     {
73         scanf("%d%d", &row, &col);
74         getchar();
75         for(int i = 0; i < row; ++i)
76         {
77             for(int j = 0; j < col; ++j)
78             {
79                 scanf("%c", &map[i][j]);
80                 vis[i][j] = MAX;
81             }
82             getchar();
83         }
84         scanf("%d%d%d%d%d", &k, &sy, &sx, &ey, &ex);
85         --sx, --sy, --ex, --ey;
86         BFS();
87     }
88     return 0;
89 }
代码君

 

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/3918065.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx(六)-- 配置文件之Gzip

1.概念及作用 Gizp主要对内容、静态文件做压缩&#xff0c;用来提升网站访问速度&#xff0c;节省带宽。 2.使用方法 gzip既可以配置在server中&#xff0c;也可以配置在server外&#xff0c;此处配置在server中&#xff0c;如下&#xff1a; 说明&#xff1a;  gizp on|off 是…

误码率越高越好还是越低越好_夜间护理步骤越多越好还是越少越好?NFF

现在很多人都知道了夜晚是护肤的黄金护肤时间&#xff0c;有些很聪明的姐妹就从夜晚着手&#xff0c;使用很多种护肤品&#xff0c;希望达到事半功倍的效果&#xff0c;但好皮肤不常有&#xff0c;皮肤问题却常有&#xff01;既然如此&#xff0c;不少人就问了&#xff0c;夜间…

【随机森林】random forests 简单介绍

Random Forest&#xff0c;顾名思义 Random 就是随机抽取&#xff1b; Forest 就是说这里不止一棵树&#xff0c;而由 一群决策树组成的一片森林 &#xff0c;连起来就是用随机抽取的方法训练出一群决策树来完成分类任务。RF用了两次随机抽取, 一次是对训练样本的随机抽取; 另一…

侧边工具开发2

1.使用图片的形式会出现大量的图片&#xff0c;影响性能&#xff0c;而且不易修改&#xff0c;所有使用图标加文字的形式进行 <a href"javacript:;" class"toolbar-item"><span class"toolbar-btn"><i class"toolbar-icon&q…

斐波那契?

斐波那契&#xff1f; Time Limit: 1000ms Memory limit: 32768K 有疑问&#xff1f;点这里^_^ 题目描述 给出一个数列的递推公式&#xff0c;希望你能计算出该数列的第N个数。递推公式如下&#xff1a; F(n)F(n-1)F(n-2)-F(n-3). 其中&#xff0c;F(1)2, F(2)3, F(3)5. 很熟…

clustalw序列比对_序列比对之Clustalx与Clustalw使用指南

相关专题这几天实验需要做多序列比对&#xff0c;很久不做了&#xff0c;一时之间不知道如何使用clustal这个工具了。在网上搜集了一些资料&#xff0c;做个整理&#xff0c;总结了Clustalx和Clustalw的使用&#xff0c;省得以后久不使用又生疏了&#xff0c;又要去整理了&…

信息安全系统设计基础第三周学习总结—20135227黄晓妍

一.Vim编辑器 1.Vim的六种模式 2.Vim三种常用模式的使用方式&#xff0c;以及三者的切换。打开Vim即默认进入普通模式&#xff0c;按i进入插入模式&#xff0c;按esc从插入模式退出普通模式&#xff0c;再按&#xff1a;进入命令行模式。 普通模式下游标的移动 按键 说明 h …

关于指定日期的获取

java使用Calendar类获得指定日期 关于指定日期的获取&#xff0c;是根据指定日期和当前日期相差的天数&#xff0c;然后使用set方法设置Calendar.DAY_OF_MONTH的值。Calendar cal Calendar.getInstance();cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - da…

nodejs的package.json依赖dependencies中 ^ 和 ~ 的区别

nodejs的package.json定义了一个模块&#xff0c;包括其依赖关系的一个简单的JSON文件&#xff0c;该文件可以包含多个不同的指令来告诉Node包管理器如何处理模块。 dependencies则表示此模块依赖的模块和版本&#xff0c;其中常常可以看到类似 ^1.2.0 或 ~1.2.0 这样的版本范围…

脚本命令_SAP HANA数据库备份命令脚本

需求场景&#xff1a;HANA数据库版本 2.044 &#xff0c; SYSTEMDB库1个&#xff0c;Tenant库有3个 PRD、POP、HAP需要用命令行备份。备份原理说明&#xff1a;1、脚本同hana studio 一样&#xff0c;用SYSTEM用户去备份所有的数据库。2、备份脚本工作在数据库管理员用户下&…

Spring 基于Java的Bean声明

Spring 基于Java的Bean声明 使用Configuration进行设置&#xff1b; Xml&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://www.springframework.…

手机音频通道被占用_关于凯叔讲故事APP的音频导出下载

孩子喜欢听凯叔讲故事&#xff0c;起先是三国演义和博物学&#xff0c;在网上听了个开头后&#xff0c;毫不犹豫买了正版,心想着购买app可以下载音频&#xff0c;完了拷贝到其他播放器听。然而......然而......大失所望&#xff0c;美其名曰保护正版&#xff0c;可这么个玩意&a…

编译安装 apache 2.4.6

如果配置apr&#xff0c;需要预先安装apr 以下是安装apache 步骤: groupadd webuser useradd -g webuser webuser 下载apache2 下载链接&#xff1a;http://pan.baidu.com/s/1ntiGWvZ 配置 ./configure --prefix/server/apache2 \ --enable-mods-sharedmost \ --enable-so \ --…

CSS3中border-radius、box-shadow与gradient那点事儿

一、border-radius border-radius用于添加圆角边框&#xff0c;用处非常广泛。 1&#xff09;一个值&#xff0c;代表了四个角 .radius-one {/* Safari 3-4, iOS 1-3.2, Android 1.6- */-webkit-border-radius: 12px; /* Firefox 1-3.6 */-moz-border-radius: 12px; /* Opera 1…

编程 跳台阶_Java版剑指offer编程题第8题--跳台阶

跟learnjiawa一起每天一道算法编程题&#xff0c;既可以增强对常用API的熟悉能力&#xff0c;也能增强自己的编程能力和解决问题的能力。算法和数据结构&#xff0c;是基础中的基础&#xff0c;更是笔试的重中之重。不积硅步&#xff0c;无以至千里&#xff1b;不积小流&#x…

获取汉字的首字母(转)

转换 获取一个汉字的拼音首字母。 GB码两个字节分别减去160&#xff0c;转换成10进制码组合就可以得到区位码例如汉字“你”的GB码是0xC4/0xE3&#xff0c;分别减去0xA0&#xf…

$ionicPopup

转自&#xff1a;http://www.ionicframework.com/docs/api/service/%24ionicPopup/ Usage A few basic examples, see below for details about all of the options available. angular.module(mySuperApp, [ionic]) .controller(PopupCtrl,function($scope, $ionicPopup, $tim…

目标规划运筹学例题doc_运筹学之目标规划(胡运权版).doc

运筹学之目标规划(胡运权版).doc第七章 目标规划1 目标规划的提出线性规划问题是讨论一个给定的线性目标函数在一组线性约束条件下的最大值或最小值问题。对于一个实际问题&#xff0c;管理科学者根据管理层决策目标的要求&#xff0c;首先确定一个目标函数以衡量不同决策的优劣…

Deep Learning(深度学习) 学习笔记(四)

神经概率语言模型&#xff0c;内容分为三块&#xff1a;问题&#xff0c;模型与准则&#xff0c;实验结果。[此节内容未完待续...] 1&#xff0c;语言模型问题 语言模型问题就是给定一个语言词典包括v个单词&#xff0c;对一个字串做出二元推断&#xff0c;推断其是否符合该语言…

Java Virtual Machine

后续完善转载于:https://www.cnblogs.com/fight-tao/p/4849167.html