北湖填坑——栈的应用

填坑 I

题目描述

 解题思路

        这题我们可以先自己举个例子找找思路:假设宽度为6,位置从左向右依次是1至6。不难可以发现如果3、4高度相等,那么我们可以在此处任意个2×1石头块使其到达我们任意想要的高度。对于相邻的2、5处,如果高度相差2的倍数(或者说奇偶性相同)我们可以在这两处放置1×2石块以及在3、4处放置2×1石块,使2、3、4、5处高度相同。之后我们对于1、6处也可类似处理。

        显然,在我们举的例子中,位置3比位置1、2后输入,却最先和位置4配对好,这符合栈后进先出的特点。因此,这题我们可以用栈来实现。

        经过我们的分析,可以看到,假定我们输入一个数据a(a 表示 i 位置的高度),如果栈非空并且a与栈顶元素的奇偶性相同(此处我们可以让a&=1,这样奇数会变成1,偶数会变成0, 都转化成0、1来比较),那么我们我们让栈顶元素出栈,否则我们让a入栈。

        当我们处理完所有数据后,显然如果栈空或者栈内只有一个元素,则说明最终可以填平。

 代码实现

#include <iostream>   
#include <stack>  
using namespace std;  
stack<int> stk;   
int main()    
{   
    int n,a;  
    while(~scanf("%d",&n))  
    {  
        while(!stk.empty()) stk.pop();  
        for(int i=1;i<=n;i++)  
        {  
            scanf("%d",&a);  
            a&=1;  
            if(!stk.empty() && a==stk.top()) stk.pop();  
            else stk.push(a);  
        }  
        if(stk.empty() || 1==stk.size()) printf("YES\n");  
        else printf("NO\n");  
    }  
    return 0;   
}  

填坑 II

题目描述

 解题思路

        有了上一题做基础,我们很容易看出这一题仍然是用栈来实现。因为本题只能用2×1的石块,所以不同于上一题相邻的两处只要奇偶性相同便可以配对,本题严格要求相邻两处高度相同方可配对。

        此外,本题和上一题还有一些不同:

  1. 如果当前输入的元素大于栈顶元素,不难想象到栈顶元素无法与后面高度相等的元素配对(说的形象点就是中间有高处挡住了,比如2 4 4 2 这种),因此我们便可以认为无法填平,终止操作了。
  2. 在结束数据输入后,如果栈内只有一个元素,那么这个元素必须是所有输入元素中最大的,这样才能填平。举个反例:4 2 2 4 1 ,显然前面四个高度要到4才可填平,但是最右边的高度是无法上升的。

代码实现

#include <iostream> 
#include <stack>
using namespace std;
stack<int> stk; 
int main()  
{ 
	int n,a;
    while(~scanf("%d",&n))
    {
    	while(!stk.empty()) stk.pop();
    	int max=0;
    	bool flag=true;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a);
	    	if(flag)//flag=true表示有可能填平
			{
				if(a>max) max=a;
	    		if(!stk.empty() && a>stk.top()) 
				{
					flag=false;//如果a大于当前栈顶值,不可能填平
				}
				else if(!stk.empty() && a==stk.top())
				{
					stk.pop();
				}
				else
				{
					stk.push(a);
				}
			}
		}
		if(stk.empty()) printf("YES\n");
		else if(stk.size()==1 && stk.top()==max) printf("YES\n");
		else printf("NO\n");
	}
  	return 0; 
} 

后记

        有人说 II 比 I 要简单得多,我却认为这两题各有千秋。这一题可能要更加形象,例子更容易举,不过考虑要更全面,分的情况要稍多一些。

        最后,对于这种有多组数据输入的题目,建议大家一定要养成定义变量时初始化的好习惯,反复使用一个栈时,每次使用前也不要忘了清空(QAQ)

        还有一个小方法,可以输入两次相同数据,如果输入结果不同,那肯定因为没有清空或忘记初始化导致的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值