ZJYYCOJ——问题 A: 132模式

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");
		}
	}
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值