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用了两次随机抽取, 一次是对训练样本的随机抽取; 另一…

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

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

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

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

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…

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

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

JavaScript 运行机制

JavaScript 运行机制 阅读目录 一、为什么JavaScript是单线程&#xff1f;二、任务队列三、事件和回调函数四、Event Loop五、定时器六、Node.js的Event Loop七、关于setTimeout的测试一、为什么JavaScript是单线程&#xff1f; JavaScript语言是单线程&#xff0c;也就是说&am…

android自定义倒计时控件示例

这篇文章主要介绍了Android秒杀倒计时自定义TextView示例&#xff0c;大家参考使用吧 自定义TextView控件TimeTextView代码&#xff1a; 复制代码 代码如下:import android.content.Context;import android.content.res.TypedArray;import android.graphics.Paint;import andro…

从gitlab上拉代码_从gitlab上拉取代码并一键部署

一、gitlab安装GitLab是一个利用Ruby on Rails开发的开源应用程序&#xff0c;实现一个自托管的Git项目仓库&#xff0c;可通过Web界面进行访问公开的或者私人项目。GitLab拥有与Github类似的功能&#xff0c;能够浏览源代码&#xff0c;管理缺陷和注释。可以管理团队对仓库的访…

产品管理流程

转载于:https://www.cnblogs.com/candle806/p/4860841.html

如何根据灰度直方图计算标准差_如何根据电器功率计算电线的粗细?

一般来说&#xff0c;测算电线的粗细&#xff0c;需要根据功率计算电流&#xff0c;根据电流选择导线截面&#xff0c;根据导线的截面&#xff0c;导线或电缆的型号查厂家的该型号的导线电缆的直径。这里就涉及了&#xff1a;电线粗细与功率之间的关系计算&#xff1b;导线截面…

解惑烟草行业工控系统如何风险评估

上周五下午&#xff0c;威努特工控安全联合创始人 赵宇 先生&#xff0c;带来了一场关于“工控系统的风险评估”的技术讲座。此次近200注册报名的朋友&#xff0c;来自各大高校、国企、外企、测评中心、安全厂商、大型集成商以及大型IT科技企业、安全实验室等。 烟草企业调研参…

UVa 11806 Cheerleaders

题意&#xff1a;m行n列的矩形网格放k个相同的石子&#xff0c;要求第一行最后一行第一列最后一列都必须有石子&#xff0c;问有多少种放法 A为第一行没有石子的方案数&#xff0c;BCD依此类推&#xff0c;全集为S 如果没有任何要求的话&#xff0c;放法数应该是C(rc, k) 解法中…

为什么说一站式移动办公SaaS平台一定是未来!

摘要&#xff1a;移动办公SaaS之间的核心竞争不在于比拼技术&#xff0c;而在于谁更好地与企业管理和文化相互融合&#xff0c;给企业带来更加年轻、更加高效的工作方式&#xff0c;实现了企业组织的互联网化。 没有哪个企业愿意当诺基亚&#xff0c;“并没有做错什么&#xff…

server sql 将出生日期转为年龄_在sql server表中有一个出生日期字段我怎么才能在当前年份改变时自动更新年龄字段...

先说明下identity(1,1)&#xff1a;自动1foreign key 外键语法create database ztxuse ztxCreate Table QAUser--baidu用户资料(Id int Primary Key not null identity(1,1),--自动编号,也同时用于对用户的标示符QA_name varchar(20),--用户名Sex char(2),--或者使用bit类型,但…

自动裁剪图片

自动裁剪商品图片View Code执行裁剪指定目录商品图片动作///<summary> ///执行指定目录商品图片动作 ///</summary> public static void FindPictureDoCutIt(object o) {string filePatho.ToString();try{DirectioryInfo fatherFolder new DirectioryInfo(filePat…

32位oracle_oracle 性能调优

pool&#xff0c;sga&#xff0c;pga的配置 物理内存16G在调整SGA前&#xff0c;先看下服务器操作系统是32位还是64位的&#xff0c;如果是32位的&#xff0c;则SGA最大不能超过1.7G&#xff0c;如果是64位的&#xff0c;则不能超过4G。基本分配原则&#xff0c;db_block_buffe…