NOIP2013 day2

1.积木大赛1

题解:我们审题发现,可以选择在一个区间能同时加积木,从而最终达到目标的 高度。我们稍微思考一下就可以得出这样的结论,如果当前的高度小于之前的高度,那么在上一步就能一起搭建好;如果当前的高度大于了之前的高度,那个就需要在上一次搭建次数上增加几次(h[i]-h[i-1])。我们转化成代码来看看

for (int i=1;i<=n;i++){
    if(h[i]>h[i-1]) 
	   ans+=h[i]-h[i-1];//只需要比较前后两块的高度,高度差就是方案数 
  }

这道题就按照这个思路去做,几分钟就做好了,下面是完整代码:

//1.积木大赛
#include<bits/stdc++.h> 
const int MAXN=99999999;
using namespace std;
int n,h[MAXN],ans,s[MAXN];
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++) 
      scanf("%d",&h[i]);
  for (int i=1;i<=n;i++){
    if(h[i]>h[i-1]) //只需要比较前后两块的高度,
	   ans+=h[i]-h[i-1];//如果当前比以前矮,高度差就是方案数的增加量 
  }
  printf("%d\n",ans);	
}

2.花匠

2

题解:这道题的大意是求最长的抖动序列。我们不妨设定一个变量flag来记录3种状态:-1初始状态,这盆花的为第一盆(即它的前面是空的);1表示前面的花高度呈上升状态;0表示前面的花高度呈下降状态。示意图
图片随手画的,做一个参考。红色箭头所指方块为当前方块(它的高度和它后面的高度暂请忽略)。了解了flag的状态代表着什么之后,接下来我们来看看怎样运用这个flag标记。

flag的运用:当flag状态为初始状态也就是-1的时候,我们先定义一个int类型的变量f记录第一盆花的高度h[1]。接着我们从2开始进行for循环比较当前花高度与前一朵高度。如果说第二朵比第一朵高,那么留下的花的数量加一,flag变量变为1;如果说第二朵高度比第一朵高,留下的花数量加一,flag变量变为0;一样高,第二朵花舍弃,数量不变,flag标记不变。

if(flag==-1)
  {
    if(h[i]>f)
      {
	ans++;
	flag=1;
       }
    else if(h[i]<f)
      {
	ans++;
        flag=0;
       }
   }
 f=h[i];//别忘了高度需要继承

接下来就是简单的if判断操作了,当前高度比之前高且flag=0,ans(留下花的数量)++;当前高度比之前高度小且flag=1,ans++。

if(h[i]==f) continue;
	  else if(h[i]<f&&flag==1)
	  {
	  	ans++;
	  	flag=0;
	  }
	  else if(h[i]>f&&flag==0)
	  {
	  	ans++;
	  	flag=1;
	  }

把所有代码结合起来,这道题就完成了,下面放出完整代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=9999999;
int n,h[MAXN],f,ans,flag=-1;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
   	   scanf("%d",&h[i]);
	f=h[1];
	ans=1;	
	for(int i=2;i<=n;i++){
	  if(h[i]==f) continue;
	  else if(h[i]<f&&flag==1)
	  {
	  	ans++;
	  	flag=0;
	  }
	  else if(h[i]>f&&flag==0)
	  {
	  	ans++;
	  	flag=1;
	  }
	  else if(flag==-1)
	  {
	  	if(h[i]>f)
		  {
	  		ans++;
	  		flag=1;
		  }
		if(h[i]<f)
		  {
			ans++;
			flag=0;
		  }
	  }
	  f=h[i];
	}
	printf("%d\n",ans);
	return 0;
}

对了,顺便推荐一下另外一种做法:sunshinezff大佬用dp做的

3.华容道

3
好吧,这道题我暂时还没那个能力讲,但是用暴力做的话能过60%。以后再更(咕咕咕)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值