2020_4_21二刷
要考虑到sq[j] < temp.top()的情况,举例来说,题目中所给的第二个出栈序列:3 2 1 7 5 6 4,当模拟到7的时候,是没有问题的,7出栈之后,出栈序列中下一个是5,而栈中元素从顶到底依次是6 5 4,所以6一定会在5之前出栈,显然这里出错了,这种出栈序列是不可能存在的。
#include<iostream>
#include<stack>
using namespace std;
int main() {
int m, n, k;
cin >> m >> n >> k;
for (int i = 0; i < k; i++) {
stack<int>temp;
int pos = 1, sq[1000], flag = 0;
for (int j = 0; j < n; j++)cin >> sq[j];
for (int j = 0; j < n; j++) {
while (temp.size() == 0 || temp.top() != sq[j]) {
temp.push(pos++);
if (temp.size() > m || sq[j] < temp.top()) {
flag = 1;
break;
}
}
if (flag == 1) break;
temp.pop();
}
if (flag == 1)cout << "NO" << endl;
else
cout << "YES" << endl;
}
return 0;
}
第一次写的时候没有用array,而是输入一个元素后进行分析处理,这样的问题是,一旦确定了res[i]是true还是false之后,还需要把剩余的元素读入,容易出现错误且繁琐。
所以改为先把一行全部输入,再进行处理。
#include<iostream>
#include<iomanip>
using namespace std;
bool res[1000];//保存k行的结果YES或NO
int main(){
int m,n,k;
cin>>m>>n>>k;
fill(res,res+999,true);
for(int i=0;i<k;i++){
int stack[1000];
int top=-1;
int array[1001];//用于输入
int mark[1000];//标记已出队元素
fill(mark,mark+999,0);
fill(stack,stack+999,0);
for(int j=1;j<=n;j++)cin>>array[j];
for(int j=1;j<=n;j++){
if(top==-1){//栈空
if(array[j]==j)mark[j]=1;//举例来说,如果第三个出栈元素恰好是3,则3直接进栈,再出栈
else{
for(int k=1;k<=array[j];k++){
if(mark[k]==0){
stack[++top]=k;
if(top==m){
res[i]=false;
break;
}
}
}
mark[array[j]]=1;
top--;
}
}
else if(stack[top]==array[j]){//举例来说,如果第三个出栈元素是7,那么7以前的未出栈元素(没有被mark标记的)
//需要先于7进栈,因为虽然出栈顺序不定,但是进栈顺序一定是小的元素先进
mark[array[j]]=1;
top--;
}
else if(stack[top]>array[j]){//大的不可能先于小的进栈
res[i]=false;
}
else{
for(int k=stack[top]+1;k<=array[j];k++){
if(mark[k]==0){
stack[++top]=k;
if(top==m){
res[i]=false;
break;
}
}
}
mark[array[j]]=1;
top--;
}
if(!res[i])break;
}
}
for(int i=0;i<k;i++){
if(res[i])cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
另一种思路:元素从小到大不断进栈,视条件出栈
#include<iostream>
#include<stack>
#define maxn 1000
int a[maxn];
using namespace std;
int main(){
int m,n,k;
stack<int>s;
cin>>m>>n>>k;
for(int i=0;i<k;i++){
int cur=0;
bool res=true;
while(!s.empty())s.pop();
for(int j=0;j<n;j++)cin>>a[j];
for(int j=1;j<=n;j++){
s.push(j);
if(s.size()>m){
res=false;
break;
}
while(!s.empty()&&(s.top()==a[cur])){
s.pop();
cur++;
}
}
if(s.empty()&&res)cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}