ZJYYCOJ——问题 A: 132模式
链接:http://acm.oinsm.com/problem.php?cid=1073&pid=0
时间限制: 1 Sec 内存限制: 32 MB
题目描述
输入一个整数序列:a1, a2, …, an,一个132模式的子序列ai, aj, ak被定义为:当 i < j < k 时,ai < ak < aj。
设计一个算法,当给定有n 个数字的序列时,验证这个序列中是否含有132模式的子序列。
输入
第一行输入序列长度n,( 0 <= n <= 15000 )
第二行输入n个数
输出
如果含有 132模式子序列输出True,否则输出False
样例输入
4
1 2 3 4
4
3 1 4 2
4
-1 3 2 0
样例输出
False
True
True
提示
第一组数据: 序列中不存在132模式的子序列
第二组数据: 序列中有 1 个132模式的子序列: [1, 4, 2]
第三组数据: 序列中有 3 个132模式的的子序列: [-1, 3, 2], [-1, 3, 0] 和 [-1, 2, 0]
刚开始理解错误,以为132模式是三个连续的数组后来发现并不是。
思路:按照2->3->1循序去找,大概思路如图所示。被压入栈的一定是是按递减关系的,所以我们要找栈内最大的而又比当前值小的,最后再找后面的值小于t的,才能保证不遗漏。
错误代码:
#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
stack<int>sk;
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
sk.push(k);
}
if(n<3){
printf("False\n");
}
else{
int a=sk.top();
sk.pop();
int b=sk.top();
sk.pop();
int len=sk.size();
int f=0;
while(!sk.empty()){
int c=sk.top();
sk.pop();
if(a<b){
if(c<a){
f=1;
break;
}
}
else{
a=b;
b=c;
}
}
if(f){
printf("True\n");
}
else{
printf("False\n");
}
}
}
}
正确代码:
#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
stack<int>sk;
int a[n+5];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
if(n<3){
printf("False\n");
}
else{
int t=-2<<30;
//cout<<t<<endl;
int f=0;
for(int i=n-1;i>=0;i--){
if(a[i]<t){
cout<<"True"<<endl;
f=1;
break;
}
while(!sk.empty()&&a[i]>sk.top()){
t=sk.top();
sk.pop();
}
sk.push(a[i]);
}
if(f==0) printf("False\n");
}
}
}