赞
踩
【问题描述】老鼠找食物,但是回家的时候找到最短路径,输入是x-y,x是1234其中一个,代表四个方向,y是向这个方向走的距离,比如:格式:数字-数字,0-0表示找到了,1-2表示向上走两步,2-3表示向下走3步,3-1表示向左走1步,4-2表示向右走两步,0-0表示找到了。
【要求】然后返回的时候,找到最短路径,然后要求给他找回头路,把重复的路给去掉,题目首先规定四个方向:1,2,3,4分别代表上下左右,输入序列形式为1-3,3-4.....,前一个数字代表方向,后一个数字代表前进距离,以0-0为结束,结束则代表老鼠找到了食物。
老鼠在碰到死路时会原路返回到分叉路口,探索下一个方向。需要求解老鼠原路返回的最佳路径,以2-3,4-2.....等作为输出。最佳路径的描述是“不走回头路”,即没有折返过程即可。
示例1:输入:
1-1 3-1 1-1 2-1 4-2 1-2 4-1 1-1 2-1 3-1 1-1 0-0
输出:
2-3 3-1 2-1
示例2:输入:1-10 0-0
输出:2-10
示例3:
输入:1-1 4-1 1-1 4-1 3-1 1-1 2-1 4-2 1-1 0-0
输出:2-1 3-1 2-1 3-1 2-1 3-1 2-1
代码思路:创建结构体存储每一步的全部动作,包括方向和步数,创建一个函数用来找到最短路径,用栈存储动作序列,判断动作方向与栈顶动作是否一致进行路径简化,最后倒序出站即为最终序列。
核心逻辑:通过将栈顶动作的方向与当前动作的方向进行比较,如果相同则合并步数,若不相反则直接压入栈中,若相反则进行减法操作。这样,简化完成后的路径就是一条没有折返过程的最佳路径。两个容器一个栈(元素是一整个数组)。最最核心:代入的基本单位为整个结构体(类似于结构体数组,但这里初始化是结构体容器)
- #include<bits/stdc++.h>
- using namespace std;
- bool panduan=true;
- struct Action{
- int direction;
- int steps;
- };
- vector<Action> shortest(vector<Action> p){//求最短路径的算法,直接返回一个结构体容器
- stack<Action> s;//用栈存储动作序列
- for(int i=0;i<p.size();i++){//将整个容器元素全部传入进行判断
- Action point= p[i];//获取当前动作
- if(s.empty()){
- s.push(point);//如果栈为空,直接将该点压入栈中
- }else{
- Action top=s.top();//获取栈顶动作,以上操作的基本单位均是结构体
- //如果当前动作与栈顶动作方向相反
- if((point.direction==1&&top.direction==2)||(point.direction==2&&point.direction==1)||(point.direction==3&&point.direction==4)||(point.direction==4&&point.direction==3)){
- //相减或者相消
- if(point.steps==top.steps){
- s.pop();//方向相反步数一样,可以认定为没有改变位置
- }else if(point.steps>top.steps){//与栈顶方向相反,走的路比栈顶元素多,重新更新栈顶方向和大小
- point.steps-=top.steps;
- s.pop();//出栈
- s.push(point);
- }else if(point.steps<top.steps){
- top.steps-=point.steps;
- s.pop();
- s.push(top);
- }
- }
- else{//如果当前动作与栈顶动作不相反,则直接将当前动作压入栈中
- s.push(point) ;
- }
- }
- }
- vector<Action> result;//用来存储结果的向量
- while(!s.empty()){//逆序进行处理栈中的元素,并合并同一方向的步数 ,遍历
- Action point=s.top();//获取栈顶元素(结构体)
- s.pop();//弹出栈顶元素(结构体)
- //方向倒置一下进行输出
- if(point.direction==1){
- point.direction=2;
- } else if(point.direction==2){
- point.direction=1;
- }else if(point.direction==3){
- point.direction=4;
- }else if(point.direction==4){
- point.direction=3;
- }
- if(!result.empty()&& point.direction==result.back().direction){//如果当前动作和结果中最后一个动作一致
- result.back().steps+=point.steps;//result.back()是对最后一个元素的引用,相当于最新加入的元素
- }else{
- result.push_back(point);//如果不同,证明方向已经改变或者是第一个元素,加入该元素。
- }
- }
- return result; //结构体向量
- }
- vector<Action> x;//存储每一步的全部信息
- int main(){
- int x1,y1;
- char xing;
- while(panduan){//读取方向,节点元素
- Action po;
- cin>>x1>>xing>>y1;
- po.direction=x1;
- po.steps=y1;
- x.push_back(po);
- if(x1==0&&y1==0){
- panduan=false;
- }
- }
- vector<Action> y=shortest(x);//再创建一个结构体向量接收返回结果
- for(int i=0;i<y.size();i++){
- Action action=y[i];
- if(action.direction==0&&action.steps==0){
- continue;
- }else{
- cout<<action.direction<<"-"<<action.steps<<endl;
- }
- }
- }
欢迎指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。