洛谷P1155 雙棧排序(貪心)
阿新 • • 發佈:2018-10-27
get org bit etc clas push vector code 滿足
題意
題目鏈接
Sol
首先不難想到一種貪心策略:能彈則彈,優先放A
然後xjb寫了寫發現只有\(40\),原因是存在需要決策的情況
比如
\(A = {10}\)
\(B = {8}\)
現在進來一個\(7\),看上去很難判斷\(7\)到底放在哪裏,如果放\(A\),後面來個\(9\),再來個\(6\),我們就涼了。
但是如果先來的是\(6\),且此時已經排完了\(1-5\),那麽我們可以在後續操作中把\(7\)弄走
仔細想想不難發現,\(7\)不能放在\(A\)中,當且僅當存在一個位置\(K\),滿足\(a[k]>7\),且在\(k\)之後有位置\(l\),滿足\(a[l]<7\)
也就是說\(i, j, k\)不能同時在棧中,當且僅當
\(i < j < k\)且\(a[k] < a[i] < a[j]\)
然後就做完了,xjb貪即可
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define NO {puts("0"); exit(0);} #define pb(x) push_back(x) using namespace std; const int MAXN = 1001; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, a[MAXN], s1[MAXN], tp1, s2[MAXN], tp2; vector<char> v; bool check(int pos) { if(!tp1) return 1; int i, j; if(a[pos] > s1[tp1]) return 0; if(!tp2) return 1; for(i = pos + 1; i <= N; i++) if(a[i] > a[pos] && a[i] > s2[tp2]) break; for(int j = i + 1; j <= N; j++) if(a[j] < a[pos]) return 0; return 1; } int main() { N = read(); for(int i = 1; i <= N; i++) a[i] = read(); int now = 1; for(int i = 1; i <= N + 1; i++) { if(a[i] == now) {now++; v.pb('a'); v.pb('b'); continue;} while(now == s1[tp1] || now == s2[tp2]) { if(now == s1[tp1]) v.pb('b'), tp1--, now++; if(now == s2[tp2]) v.pb('d'), tp2--, now++; } if(i == N + 1) break; if(check(i)) {v.pb('a'); s1[++tp1] = a[i]; continue;} if(!tp2 || a[i] < s2[tp2]) {v.pb('c'); s2[++tp2] = a[i]; continue;} NO; } if(tp1 || tp2) NO; for(int i = 0; i < v.size(); i++) putchar(v[i]), putchar(' '); return 0; }
洛谷P1155 雙棧排序(貪心)