这道题很多题解说是二分图染色+模拟,然而其实一个贪心就够了。
如果s1或s2当前栈顶的元素刚好是排好序后的第k个数,那么自然要弹出栈;否则贪心的放入s1栈,同时要判断合法性;如果不行,再看看能否放入s2;如果还不行就输出0。
判断能否放入s1就是看看这个数之后如果有超过两个比s2栈顶元素还大的数的话,就不合法,否则合法。因为如果有一个比s2大的话,还可以通过后来的操作放入两个栈中,但是两个就不可能了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e3 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int n, t[maxn]; 38 int a[maxn], b[maxn], cnt = 0; 39 char ans[maxn << 1]; 40 bool flg = 1; 41 42 bool check(int x, int bi) 43 { 44 if(!bi) return 1; 45 int i; 46 for(i = x + 1; i <= n; ++i) if(t[i] > t[x] && t[i] > b[bi]) break; 47 for(int j = i + 1; j <= n; ++j) if(t[j] < t[x]) return 0; 48 return 1; 49 } 50 51 int main() 52 { 53 n = read(); 54 for(int i = 1; i <= n; ++i) t[i] = read(); 55 a[0] = b[0] = INF; 56 for(int i = 1, ai = 0, bi = 0, ti = 1, num = 1; i <= (n << 1); ++i) 57 { 58 if(a[ai] == num) 59 { 60 ai--; num++; 61 ans[++cnt] = 'b'; 62 } 63 else if(b[bi] == num) 64 { 65 bi--; num++; 66 ans[++cnt] = 'd'; 67 } 68 else if(ti <= n && t[ti] < a[ai] && check(ti, bi)) 69 { 70 a[++ai] = t[ti++]; 71 ans[++cnt] = 'a'; 72 } 73 else if(ti <= n && t[ti] < b[bi]) 74 { 75 b[++bi] = t[ti++]; 76 ans[++cnt] = 'c'; 77 } 78 else {flg = 0; break;} 79 } 80 if(!flg) puts("0"); 81 else for(int i = 1; i <= cnt; ++i) printf("%c%c", ans[i], i == cnt ? ' ' : ' '); 82 return 0; 83 }