这题蛋疼......开始看题目以为只要判断是否逆序就出来了,后来发现人家网上说【并不是说必须所有的车都进站了 才可以统一按顺序出来,而是说可以先进入一辆车然后这辆车出来,然后再进下一辆车,也可以先进两辆然后出来一辆再进一辆,即何时进站何时出站都可以....】才恍然大悟....
所以这题思路就很明确了,只要看出栈的顺序即可,如题目:入栈串 O1 出栈串O2 栈用STACK表示
所以基本思路就是:
注:中途出现栈中数量为9但是依然需要push也是no,题意说车站(栈)最多进9个列车
(1):看O2的第一个元素是啥,假如是3,那么就读取入栈O1,直到读取到3为止(或者读取超过9个失败输出"no"),将3入栈再出栈(模拟了入车站,出车站)
(2)重复步骤 1(第一个元素下标换成下一个) =>速度加快判断可以去 (3)
(3)做完步骤(1)【这时候就要看O2的第二个元素是啥,假设是4,那么看这个元素是否已经在栈中,如果已经在栈中,那么看它是否是栈的top元素,如果不是说明"no"(此类情况出现可以直接得出结论,加速判断) 因为现在出栈O2要出4,但是栈中有一个元素在4前面,(为了方便理解假设现在top是2)那么4要出来2一定要出来,而且2出在了4的前面,因此肯定是不合适的....如果top元素就是现在O2要出的,那么好办就把它出栈出来即可】,返回步骤(1)[此时直接返回步骤即可,O2下一个元素是不是在栈中已经不重要,如果在栈中,那么栈要么会超过9个失败,或者O1顺序全部进栈...退出第二个while,到达下面的if被find发现失败]
//虽然这个代码被AC了但是仔细的思考,感觉逻辑有漏洞 [= =~]
如果是步骤(1)做完,返回继续进行步骤(1),有没有这种情况发生,就是 a 元素已经在栈中,并且不是top元素,那么读取O1元素和O2下一个元素比较的时候,会由于两个元素不一样而一直入栈,此时会有2种情况:
a.超过9列失败
b.没有9列车,但是O1被读取光了...发生越界....
所以 while (STACK_idenx<9&&O1_index<n&&STACK[STACK_idenx] != O2[O2_index]) //加上了对于O1界限的限制
然后此时依旧有问题,对于第一层的while(O2_index<n)的判断标准依旧是合法的无限死循环....但是此种情况已经是失败的....
所以....突然发现....虚线部分是可以拯救世界的.....此种情况(已在栈中并且非栈顶元素)可以break
---------------------------------------------------------------------------------------------------------------------------------
综上所述:
while (STACK_idenx<9&&O1_index<n&&STACK[STACK_idenx] != O2[O2_index]) //加上了对于O1界限的限制
虚线部分不删除,即可
# include<iostream>
using namespace std;
char O1[1000];//入栈
char O2[1000];//出栈
char STACK[9];//模拟车站最多只有9列
bool Path[2000];// 0 入栈 1 出栈
bool find(char*s, int n, char a) {
int i ;
for (i = n; i >= 0; i--) {
if (s[i] == a)
return true;
}
return false;
}
int main(void) {
int n,O1_index,O2_index,STACK_idenx,Path_index;
bool IS_OK;
while (cin >> n) {
cin >> O1 >> O2;
O1_index = O2_index = STACK_idenx = Path_index = 0;
IS_OK = true;
while (O2_index < n) {//检查的条件 出栈顺序数组没空
if (!O1_index) {//将第一个数入栈
STACK[STACK_idenx] = O1[O1_index++];
Path[Path_index++] = 0;
}
while (STACK_idenx<9&&O1_index<n&&STACK[STACK_idenx] != O2[O2_index])
{//原错误写法: while (STACK_idenx<9&&STACK[STACK_idenx] != O2[O2_index])
//(1)栈中还能push(2)还有入栈元素(3)栈顶不等于出栈顺序
//并不等于出栈的列车
STACK_idenx++;
STACK[STACK_idenx] = O1[O1_index++];//将第二数字继续入栈
Path[Path_index++] = 0;//记录入栈的路径
}//最终必然找到了和出栈顺序一样的(或者站满)
if (STACK[STACK_idenx] == O2[O2_index++]) {//如果栈顶元素等于出栈元素
Path[Path_index++] = 1;//出栈
STACK_idenx--;
}
if (STACK_idenx == 9)
{
IS_OK = false;
break;
}
//虚线处不写,不影响AC,但是影响逻辑正确性,而且可以加快判断
//-----------------------------------------------------------
if (O2_index < n) {//出栈顺序下标合法
if (find(STACK, STACK_idenx, O2[O2_index])) {//此时检查出栈的下个数字是否在栈中(前提出栈数本身在合法范围内)
if (STACK[STACK_idenx] == O2[O2_index++]) {
//现在的出栈元素就是原来出栈队列的下一个数字,出栈
Path[Path_index++] = 1;
STACK_idenx--;
}
else {//出现此种情况可以快速出来,减少了很多次入栈
IS_OK = false;
break;
}
}//else继续进行while() push 进栈
}//检查是否出栈顺序下标合法
//------------------------------------------------------------
}
if (IS_OK) {
cout << "Yes." << endl;
for (int i = 0; i < Path_index; ++i)
if (Path[i])
cout << "out" << endl;
else
cout << "in" << endl;
cout << "FINISH" << endl;
}
else {
cout << "No." << endl;
cout << "FINISH" << endl;
}
}
system("pause");
return 0;
}
下面这份代码是用栈写的一次....特么WA了....并没有啥问题....
# include <iostream>
# include <stack>
using namespace std;
int main(void) {
stack<char>STACK;
int n;
char O1[1000];
char O2[1000];
bool Path[2000];
bool IS_OK;// 0入 1 出
int O1_i, O2_i, P_i, i;
while (cin >> n) {
cin >> O1 >> O2;
O1_i = O2_i = P_i = 0;
IS_OK = true;
memset(Path, 0, sizeof(Path));
STACK.push(O1[O1_i++]);//将第一个元素入栈
Path[P_i++] = 0;
while (O2_i < n) {
while (O1_i < n&&STACK.size() < 9 && STACK.top() != O2[O2_i]) {
STACK.push(O1[O1_i++]);
Path[P_i++] = 0;
}
if (STACK.top() == O2[O2_i]) {//栈顶元素等于出栈元素
O2_i++;//必须里面自加
STACK.pop();
Path[P_i++] = 1;
}
if (STACK.size() == 9) {//栈满失败
IS_OK = false;
break;
}
if (O1_i == n) {//所有元素全部入栈了
if (O2_i < n) {
if (STACK.top() != O2[O2_i]) {
IS_OK = false;
break;
}
else {//栈顶就是出栈
STACK.pop();
Path[P_i++] = 1;
O2_i++;
}
}
}
}//while(O2_i<n)
if (IS_OK) {
cout << "Yes." << endl;
for ( i = 0; i < P_i; ++i)
if (Path[i])
cout << "out" << endl;
else
cout << "in" << endl;
}
else
cout << "No." << endl;
cout << "FINISH" << endl;
}
system("pause");
return 0;
}