【 OJ 】 HDOJ1022 18年10月31日21:41 [ 21 ]
這題蛋疼......開始看題目以為只要判斷是否逆序就出來了,後來發現人家網上說【並不是說必須所有的車都進站了 才可以統一按順序出來,而是說可以先進入一輛車然後這輛車出來,然後再進下一輛車,也可以先進兩輛然後出來一輛再進一輛,即何時進站何時出站都可以....】才恍然大悟....
所以這題思路就很明確了,只要看出棧的順序即可,如題目:入棧串 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;
}