寒假假期训练学习总结及反思 2022/1/4

一,种树问题-贪心算法

 

Description
某条街被划为 n 条路段,这 n 条路段依次编号为 1…n。每个路段最多可以种一棵树。现在居民们给出了 h 组建议,每组建议包含三个整数 b,e,t 表示居民希望在路段 b 到 e之间至少要种 t 棵树。这些建议所给路段的区间可以交叉。请问:如果要满足所有居民的建议,至少要种多少棵树。

Input
第一行为 n,表示路段数。第二行为 h,表示建议数。 下面 h 行描述一条建议:b,e,t 用一个空格分隔。

Output
  输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。

思路

以样例为例,首先按右端点升序排序:要使种的树数目最少,实际是要使树尽可能的种在路段重复地段。类似于安排时间表的问题,用贪心算法处理。排好序后按照路段顺序遍历,并且每次从最右端点向左遍历该路段,即从最右端开始种树。这样可以实现最大限度的把树优先种在重复路段。

代码

  1. #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+7;
    struct tree
    {
    	int b,e,t;
    }s[5010];
    bool cmp(tree k,tree l)
    {
    	return k.e<l.e;
    }
    int flag[90000];
    int main()
    {
        int i,j,k,sum=0,n,h;
    	scanf("%d%d",&n,&h);
    	for(i=0;i<h;i++)
    	{scanf("%d%d%d",&s[i].b,&s[i].e,&s[i].t);
    	}
    	sort(s,s+h,cmp);
    	for(i=0;i<h;i++)
    	{
    		k=0;
    		for(j=s[i].e;j>=s[i].b;j--)
    		{
    			if(flag[j]==1)
    			k++;
    		}
    		if(k>=s[i].t) continue;
    		for(j=s[i].e;j>=s[i].b;j--)
    		{
    			if(flag[j]==0)
    			{
    				flag[j]=1;k++;sum++;
    			}
    			if(k>=s[i].t) break;
    		}
    	}
    	printf("%d\n",sum);
        return 0;
    }

二,括号匹配

1.Description

烤烤最近在一家数据公司实习。实习生嘛,被分配到的总是特别枯燥的任务,他的任务是对一串字符(不超过50个字符,可能包括括号、数字、字母、标点符号、空格)进行字符匹配的判断。

要求检查这一串字符中的( ) ,[ ],{ }是否匹配。做了一上午,烤烤眼睛都看花了,所以希望你来帮帮他 !

Input

输入数据有多组,每组数据不超过100个字符并含有( ,) ,[, ],{, }一个或多个。处理到文件结束。

Output

如果匹配就输出“yes”,不匹配输出“no”

2. 解析
碰上左边括号压入栈,碰上右边括号则判断:
a. 此时栈内是否有元素(注意这个要放在第一个判断,之后代码会详解)
b. 栈顶元素是否与其配对
若两个条件都满足则把左括号压出,继续判断下一个;若不满足则结束判断,返回“False”。
最后字符数组所有元素判断完后,再次判断栈内是否有元素。
a. 若有元素,则该元素定是未匹配的,返回“False”;
b. 若无元素,则此次括号匹配判断成功。

3. 代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
bool cmp(char a,char b)
{
	return a=='['&&b==']'||a=='('&&b==')'||a=='{'&&b=='}';
}
int main()
{
	char a[200];
    int i,j,k,len,sum,t,flag;
	while(gets(a))
	{
		stack<char>s;
		flag=1;
		len=strlen(a);
		for(i=0;i<len;i++)
		{
			if(a[i]=='['||a[i]=='{'||a[i]=='(')
			s.push(a[i]);
			else if(a[i]==']'||a[i]=='}'||a[i]==')')
			{
				if(!s.empty()&&cmp(s.top(),a[i]))
				s.pop();
				else
				{
					printf("no\n");
					flag=0;break;
				}
			}
		}
		if(flag)
		{
			if(s.empty())
			printf("yes\n");
			else
			printf("no\n");
		}
	}
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值