Train Problem I(火车进站问题)hdu1022

问题

Train Problem I - http://acm.hdu.edu.cn/showproblem.php?pid=1022

分析

  1. 堆栈的核心逻辑就是“先进后出” 或 “后进先出”。
  2. 堆栈逻辑可以通俗地想象成“死胡同”逻辑,进入死胡同者必须原路返回才能出死胡同。如果进入者在离开前,有其他人进入,则后者堵住了前者的出路,前者要想离开,则必须等后者离开。
  3. 本题的火车站就是一个死胡同,对于某列火车而言,或者进站后马上出站,或者停留一段时间后再出站,且在停留期间有其他火车进站,且后者堵住了前者。
  4. 因此本题可以看成是堆栈的一个具体应用。
  5. 对于第1列出站的火车,必然是进入后马上离开,否则第一个离开的不可能是它;
  6. 对于第2列离开的火车,要么在第1列离开的火车前1个进站,要么在第1列火车离开后再进的站(马上或间隔一段时间);
  7. ……
  8. 对与第k列离开的火车,要么在第k-1列离开的火车前1个进站,要么在第k-1列火车离开后再进的站(马上或间隔一段时间);
  9. 入站序列为123时,123、231、321 、132都是合法的出站序列

思路

关键:遍历入站序列 ——原因:只有火车进入了车站才能离开车站,因此入站是前提;一列火车进入车站就有可能马上离开车站,而且还可能导致更多的火车离开;当车站内的车无法离开时,只能让尚未进入车站的火车继续入站。因此:

  1. 初始时刻,p1、p2分别指向入站、出站序列的第一个元素
  2. 若p1指向入站序列尾部,则5;否则,将p1指向的入站元素压栈,并使p1指向下一个元素
  3. 栈顶元素与p2指向的元素比较, 若不相等,则返回2
  4. 若相等,则弹出栈顶元素,并使p2指向下一个元素,然后返回3
  5. 判断栈内元素情况,输出结果
  6. s.push(’#’),设置哨兵,栈永不空

代码

#include 
using namespace std;
int n, k, p1, p2, op[25];
char o1[25], o2[25];
int main(){
     
    while(scanf("%d", &n) == 1){
     
        stack<char> s;
        s.push('#')scanf("%s %s", o1, o2);
        p1 = p2 = k = 0;
        while(o1[p1] != '\0'){
     
            op[k++] = 1, s.push(o1[p1++]);
            while(o2[p2] == s.top())
            	s.pop(), p2++, op[k++] = 0;
        }
        if(s.top() != '#')
        	printf("No.\n");
        else{
     
            printf("Yes.\n");
            for(int i = 0; i < k; i++)
                printf("%s\n", op[i] == 1 ? "in" : "out");
        }
        printf("FINISH\n");
    }
    return 0;
}

你可能感兴趣的:(Train Problem I(火车进站问题)hdu1022)