4.6日NOIP普及组模拟赛 总结

4.6日NOIP普及组模拟赛 总结

这一次普及组模拟赛我考了268分,还可以。

第一题:表达式括号匹配

题目链接
讲题视频链接
解题思路:
这道题目用双重循环可以暴力过。
但是最优解是栈——一种数据结构(是先进后出—— F I L O FILO FILO 的数据结构)
方法:
我们遇到一个左括号,统计变量就加 1 1 1
我们遇到一个右括号,统计变量就减 1 1 1
如果最后这个变量等于 0 0 0,代表栈为空,也就意味着括号匹配成功。
但是,这种方法有一个问题,比如这个数据:
( ) ) ( ())( ())(
这个数据答案是 n o no no,但是最后的变量为 0 0 0,答案是 y e s yes yes,那么就有问题了。
其实我们发现,只要某一个时间点右括号的数量大于左括号的数量,就是不匹配的。
也就是说,如果这个变量在某一个时刻小于 0 0 0了,那么就输出 n o no no
代码如下:

#include<bits/stdc++.h>
using namespace std;
int m;
int main()
{
	char x;
	x=getchar();
	while(x!='@')
	{
		if(x=='(') m++;
		if(x==')') m--;
		if(m<0) 
		{
			printf("NO");
			return 0;
		}
		x=getchar();
	}
	if(m==0) printf("YES");
	else printf("NO");
}

第二题:数的划分

题目链接
讲题视频链接
解题思路:
这道题目的方法是暴力。
直接递归就行了,数据可以卡过。
代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,k,ans;
void dfs(int y,int x,int pre)
{
	if(x==0)
	{
		if(y==0) ans++;
		return;
	}
	for(int i=pre;i<=y/x;i++)
	{
		if(y-i<0) break;
		dfs(y-i,x-1,i);
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	dfs(n,k,1);
	printf("%d",ans);
}

至于更快的方法,是有的——动态规划、记忆化搜索等等。

第三题:小朋友的数字

题目链接
讲题视频链接
解题思路:
这道题的方法是动态规划。
其实我们要求的就是 1 1 1 i i i之间的最大连续子段和。
f i f_i fi表示以 i i i为结尾的最大子段和, d p i dp_i dpi表示 1 1 1 i i i之间的最大子段和。

f i = m a x ( f i − 1 + a i , a i ) f_i=max(f_{i-1}+a_i,a_i) fi=max(fi1+ai,ai)
d p i = m a x ( d p i − 1 , f i ) dp_i=max(dp_{i-1},f_i) dpi=max(dpi1,fi)
那么我们只用递推求最大数就行了。
但是可能会爆 l o n g l o n g long long longlong,所以要边模边做。

第四题:道路游戏

题目链接
讲题视频链接
解题思路:
用搜索可以得28分。
正解是动态规划。
反正我不会

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值