UVA816 Abbott's Revenge (三元组BFS)

题目描述:

输入输出:

输入样例:

SAMPLE
3 1 N 3 3
1 1 WL NR *
1 2 WLF NR ER *
1 3 NL ER *
2 1 SL WR NF *
2 2 SL WF ELF *
2 3 SFR EL *
0
NOSOLUTION
3 1 N 3 2
1 1 WL NR *
1 2 NL ER *
2 1 SL WR NFR *
2 2 SR EL *
0
END
输出样例
SAMPLE
(3,1) (2,1) (1,1) (1,2) (2,2) (2,3) (1,3) (1,2) (1,1) (2,1)
(2,2) (1,2) (1,3) (2,3) (3,3)
NOSOLUTION
No Solution Possible
思路:
将普通图(只含有两个方向的平面图)改为三元组表示的图,再在“平面图”的基础上调用BFS算法,求单元最短路径。输入输出很繁(对我这个菜鸡来说)。
还有就是行走函数根据转向不同将char类型的方向映射到两个一维的int上去的方式很巧妙(巧妙的加3加1取余4,就打乱原来的NESW逆时针顺序),
再通过dr,dc数组实现方向的变化和移动。
注意初始位置(r1,c1)不是原始位置(r0,c0)。
开始将d数组初始化为-1,到d[r1][c1][dir]就为0(加了1)。所以在用vector反着打印路径时最后加一个(r0,c0)(未存)

代码:(有详细的但也难懂的注释)
  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6 #define max_n 10
  7 using namespace std;
  8 struct Node
  9 {
 10     int r;
 11     int c;
 12     int dir;
 13     Node(int r1=0,int c1=0,int d1=0) :r(r1),c(c1),dir(d1) {}
 14     //构造Node,带有默认参数,不然会在Node p[][][]那里报错,认为这个语句是在构造Node
 15 };
 16 int d[max_n][max_n][4];//表示初始状态到(r,c,dir)的最短路长度
 17 Node p[max_n][max_n][4];//保存了状态(r,c,dir)在BFS数中的父结点
 18 int has_edge[max_n][max_n][4][3];//当前状态是(r,c,dir),是否可以沿着转弯方向turn行走
 19 
 20 //行走
 21 const char* dirs = "NESW"; //顺时针旋转的顺序
 22 const char* turns = "FLR";
 23 int dir_id(char c) {return strchr(dirs,c)-dirs;} //将char类型的dir转化为dirs中相应的所在位置
 24 int turn_id(char c) {return strchr(turns,c)-turns;}//将char类型的turn在turns中找到对应的元素位置
 25 const int dr[] = {-1,0,1,0};//用上面找到的元素位置来确定当前行行走方向
 26 const int dc[] = {0,1,0,-1};//用上面找到的元素位置来确定当前列行走方向
 27 char maze[21];//迷宫名称
 28 int r0,c0,dir;//原始位置和方向
 29 int r1,c1;//初始位置和方向
 30 int r2,c2;//目标位置
 31 //巧妙的行走函数和对应关系
 32 //dirs 0N 1E 2S 3W
 33 //顺时针
 34 //dir' 3  0  1  2
 35 //逆时针
 36 //dir' 1  2  3  0
 37 //dr  -1  0  1  0
 38 //dc   0  1  0 -1
 39 Node walk(const Node& u,int turn)
 40 {
 41     int dir = u.dir;
 42     if(turn==1) dir = (dir+3)%4;
 43     if(turn==2) dir = (dir+1)%4;
 44     return Node(u.r+dr[dir],u.c+dc[dir],dir);
 45 }
 46 //判断越界函数
 47 int inside(int r,int c)
 48 {
 49     return 0<r&&r<=9&&0<c&&c<=9;
 50 }
 51 //输出函数
 52 //要求:
 53 //第一行输出迷宫名
 54 //后几行输出路径,且除最后一行外,其他每行都是空两格+10个(r,c)形式空格分隔的坐标
 55 void printa(Node u)
 56 {
 57     vector<Node> nodes;//可用递归方式打印,但可能溢栈,可改用循环,用vector存储
 58     for(;;)
 59     {
 60         nodes.push_back(u);
 61         if(d[u.r][u.c][u.dir]==0) break;
 62         u = p[u.r][u.c][u.dir];
 63     }
 64     nodes.push_back(Node(r0,c0,dir));
 65 
 66     int cnt = 0;
 67     for(int i = nodes.size()-1;i>=0;i--)
 68     {
 69         if(cnt%10==0) //值得品味的细节1
 70         {
 71             printf(" ");
 72         }
 73         printf(" (%d,%d)",nodes[i].r,nodes[i].c);
 74         if(++cnt%10==0)//值得品味的细节2
 75         {
 76             printf("\n");
 77         }
 78     }
 79     if(nodes.size()%10!=0)
 80     {
 81         printf("\n");
 82     }
 83 }
 84 //输入函数
 85 //先读入迷宫名,若为END返回0,
 86 //然后一行读入起点r,c,dir,终点r,c
 87 //然后处理交叉处的方向改变,将这些信息用数组has_edge[r][c][dir][turn]记录下来,为以后BFS提供基础
 88 //读到*结束小循环,读到0结束大循环
 89 int read()
 90 {
 91     cin >> maze;
 92     if(maze[0]=='E'&&maze[1]=='N'&&maze[2]=='D'&&strlen(maze)==3) return 0;
 93     cout << maze << endl;
 94     memset(maze,0,sizeof(maze[0]));
 95 
 96     char dirs;
 97     cin >> r0 >> c0 >> dirs >> r2 >> c2;
 98     dir = dir_id(dirs);
 99     r1 = r0+dr[dir];
100     c1 = c0+dc[dir];
101     memset(has_edge,0,sizeof(has_edge));
102 
103     for(;;)
104     {
105         int r,c;
106         cin >> r;
107         if(r==0)
108         {
109             break;
110         }
111         cin >> c;
112         char chr[99];
113         while(cin >> chr)
114         {
115             if(chr[0]=='*')
116             {
117                 break;
118             }
119             for(int i = 1;i<strlen(chr);i++)
120             {
121                 has_edge[r][c][dir_id(chr[0])][turn_id(chr[i])] = 1;
122             }
123             //cout << r << " " << c << " " << chr << endl;
124             memset(chr,0,sizeof(chr[0]));
125         }
126     }
127     return true;
128 }
129 //BFS主过程
130 void solve()
131 {
132     queue<Node>q;
133     memset(d,-1,sizeof(d));
134     Node u(r1,c1,dir);
135     d[u.r][u.c][u.dir] = 0;
136     q.push(u);
137     while(!q.empty())
138     {
139         Node u = q.front();q.pop();
140         if(u.r==r2&&u.c==c2)
141         {
142             printa(u);
143             return;
144         }
145         for(int i = 0;i<3;i++)
146         {
147             Node v = walk(u,i);
148             if(has_edge[u.r][u.c][u.dir][i]&&inside(v.r,v.c)&&d[v.r][v.c][v.dir]<0)
149             {
150                 d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] +1;
151                 p[v.r][v.c][v.dir] = u;
152                 q.push(v);
153             }
154 
155         }
156     }
157     printf("  No Solution Possible\n");
158 }
159 int main()
160 {
161     while(read())
162     solve();
163     return 0;
164 }

 

转载于:https://www.cnblogs.com/zhanhonhao/p/11229296.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
基于hal库的OLED显示屏驱动C语言实现源码.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值