【 OJ 】 HDOJ1022 18年10月31日21:41 [ 21 ]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QingCoffe/article/details/83591310

这题蛋疼......开始看题目以为只要判断是否逆序就出来了,后来发现人家网上说【并不是说必须所有的车都进站了  才可以统一按顺序出来,而是说可以先进入一辆车然后这辆车出来,然后再进下一辆车,也可以先进两辆然后出来一辆再进一辆,即何时进站何时出站都可以....】才恍然大悟....

所以这题思路就很明确了,只要看出栈的顺序即可,如题目:入栈串 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;
}

猜你喜欢

转载自blog.csdn.net/QingCoffe/article/details/83591310