CF-286C. Main Sequence(贪心,模拟)

洛谷传送门

CF传送门


解题思路

先考虑没有限制负数的情况,很显然就是用一个栈,每次与栈顶能配对就配对。

当有限制负数时,会出现错误,如 1 1 3 3 -1 -1,此时我们不能让前两个1相配对。

这是进行以下两个改动:

  • 因为要求是正数在负数前面,所以我们进行倒序枚举。
  • 若当前数要求为负数,则直接入栈。若为正数且与栈顶能配对,则直接配对,并把栈顶定为负数。

最后如果栈为空,则最终可以配对成功,否则不成功。

AC代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<stack>
 7 using namespace std;
 8 const int maxn=1000005;
 9 stack<int> s;
10 int n,m,a[maxn],vis[maxn];
11 int main(){
12     cin>>n;
13     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
14     cin>>m;
15     for(int i=1;i<=m;i++){
16         int x;
17         scanf("%d",&x);
18         vis[x]=1;
19     }
20     for(int i=n;i>=1;i--){
21         if(s.empty()){
22             s.push(i);
23         }else{
24             if(vis[i]) s.push(i);
25             else if(a[i]==a[s.top()]){
26                 if(vis[i]==0){
27                     vis[i]=1;
28                     vis[s.top()]=-1;
29                     s.pop();
30                 }else{
31                     s.push(i);
32                 }
33             }else{
34                 s.push(i);
35             }
36         }
37     }
38     if(!s.empty()){
39         cout<<"NO"<<endl;
40     }else{
41         cout<<"YES"<<endl;
42         for(int i=1;i<=n;i++) cout<<a[i]*vis[i]<<" ";
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/yinyuqin/p/14428595.html