首页 > 其他分享 >蓝桥杯模拟赛(第一期)个人题解&感想

蓝桥杯模拟赛(第一期)个人题解&感想

时间:2024-11-16 16:47:26浏览次数:3  
标签:case cnt int 题解 31 感想 蓝桥 include day

林专大一牲第一次写blog,更新较慢,写的不好的地方请见谅(好多题目忘记了题号 and 暂时没有题目要求的内容…后面会补充的!)

本次带来的是蓝桥杯模拟赛第一期的个人题解(笨人水平较低,大家可以在评论区指出错误/讨论更优解~) 大多题我是用c++写的,但也掺了几道c,为以后全面用c++打比赛作过渡!

填空题

T? 日期问题(模拟)

(意难平)

日期问题嘛,直接就能想到把日期视为八位数(如2024/11/16看作20241116这个数)。循环遍历判断是否满足要求。然后就可以开始愉快地写代码了

在check_valid函数中,首先判断day是否满足1、21、31(即day%10==1) 不满足就return false;后面判断日期是否合法就是很自然的写法。

再然后就会遇到一个问题:check_good函数里怎么判断某一天是不是周一?在草稿纸上举几个例子就不难想到,已知1901.1.1.为星期二,和这一天的天数差day_gap%7==6的话那这天就是周一(距离最近的就是1901.1.21.)

天数差=年份差*365+闰年补充天数+当年与1.1.相差天数

(在check_good函数里,从1901年到目标年份的前一年,每遇到一个闰年天数差就要多一天)

笨人在考场上计算天数差时漏掉了年份差*365这一部分,也没检查就自信提交了(大哭

这么一道填空就水灵灵地爆掉了…血的教训(以后一定注意!!)

下面是赛后微修代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//计算某天与1月1日的天数差
//switch里不写break,利用找到入口后一直执行cnt+=
int caculate_days(int year,int month,int day)
{
	int cnt=0;
	switch(month)
	{
		case 12:cnt+=30;
		case 11:cnt+=31;
		case 10:cnt+=30;
		case 9:cnt+=31;
		case 8:cnt+=31;
		case 7:cnt+=30;
		case 6:cnt+=31;
		case 5:cnt+=30;
		case 4:cnt+=31;
		case 3:if(year%100&&year%4==0||year%400==0)cnt++;
		cnt+=28;
		case 2:cnt+=31;
		case 1:cnt+=day-1;
	}
	return cnt;
}
//判断日期是否合法
bool check_valid(int year,int month,int day)
{
	if(day%10!=1) return false;
	if(month==0||month>12) return false;
	if(day==0||month!=2&&day>days[month]) return false;
	if(month==2)
	{
		//leap来控制平/闰年(在day>28+leap体现),leap在右式为真即为1,右式为假即为0
		int leap=year%100&&year%4==0||year%400==0;
		if(day>28+leap) return false;
	}
	return true;
}
//判断日期是否是好的周一
bool check_good(int year,int month,int day)
{
	int st=1901;
	//初始化天数差并补充在year之前的所有闰年
	int day_gap=(year-1901)*365%7;
	for(st;st<year;st++)
	{
		if(st%100&&st%4==0||st%400==0) day_gap++; 
	}
	//当年如果是闰年且在二月份之后,再补充一天
	if(year%100&&year%4==0||year%400==0)
	{
		if(month>2) day_gap++;
	}
	day_gap%=7;
	day_gap+=(caculate_days(year,month,day)%7);
	day_gap%=7;
	if(day_gap==6) return true;
	return false;
}
int main()
{
	int res=0;
	//把年月日看作八位数,模拟每个八位数检查其是否满足所有条件
	for(int date=19010101;date<=20241231;date++)
	{
		int year=date/10000;
		int month=date%10000/100;
		int day=date%100;
		if(check_valid(year,month,day)&&check_good(year,month,day))
		{
			res++;
		}
	}
	printf("%d\n",res);
	return 0;
}

这个程序的结果为762

编程题

T?(脑筋急转弯)

刚看到这道题我直接在想要用分离数位再处理还是直接用字符读入…(明显做题有点赶) 

然后突然就发现这题只需要找到最大的那一个数字就行了(比如82020009,起决定性作用的是9)

这个就话不多说,上代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int main()
{
	long long n;
	cin>>n;
	int maxv=-1;
	while(n)
	{
		int t=n%10;
		maxv=max(maxv,t);
		n/=10;
	}
	cout<<maxv;
	return 0;
}

T10(DP)

当时就莫名感觉有点最长上升子序列的影子(当然我也是这么处理的)

这道题我是这样考虑的:把这个问题拆分成某元素左边的最长递减子序列长度+右边的最长递增子序列长度(用动态规划就能做到这一点,且时间复杂度为O(n^2)。预处理完dp1[]和dp2[]后,遍历a[]中每个元素,并更新满足要求的最长答案(不要忘记加上这个元素本身)

聪明的小伙伴肯定发现了,这个显然是有点小问题的。也确实,提前一个半小时我就交卷了…交完就灵光一闪(bushi)忘记了题目中有个要求是: 最后那个数是最大的

显然考场上写的代码没有考虑这一点orz(只希望数据别太卡这一个要求吧…这也提醒我下次要细心,不要写代码投入到最后漏掉部分条件)(也可能读题不够仔细(划掉

我抽空看看再把漏掉的要求补上吧

下方DP应该是部分分:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N=1010;

int n;
int a[N];
int dp1[N],dp2[N];
//dp1[i]表示a[i]前严格递减子序列的最长长度
//dp2[i]表示a[i]后严格递增子序列的最长长度

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	//预处理dp1[]
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<i;j++)
		{
			if(a[j]>a[i]) dp1[i]=max(dp1[i],dp1[j]+1);
		}
	}
	//预处理dp2[]
	for(int i=n;i>=1;i--)
	{
		for(int j=n;j>=i;j--)
		{
			if(a[j]>a[i]) dp2[i]=max(dp2[i],dp2[j]+1);
		}
	} 
	//遍历元素,其前最长递增子序列+其后最长递增 +1(其自身)即为所求
	int res=0;
	for(int i=1;i<=n;i++)
	{
		res=max(res,dp1[i]+dp2[i]+1);
	}
	cout<<res;
	return 0;
}

总结

总体来说题目难度适中,也没有用到太多算法知识,题目随题号基本由易到难。

在写代码之前还是要先想清楚一些细节,不然写代码的时候很可能就会漏掉那一丢丢,最后导致重大事故(bushi),尤其是填空题

还有就是考场上的每一分钟都很重要,还是要好好检查代码的(不要太提前交卷!),写一遍就过but没有考虑全面的时候很多!最好是全做完再来仔细看遍题目,想下代码有没有完整实现要求,再举出一些极端情况/一般情况的样例进行调试(比如T10)

这是一个全新的开始,平时还是要多做题,找灵感。争取在下一次比赛中稳扎稳打,改掉本次比赛出现的问题。

未完待续…

标签:case,cnt,int,题解,31,感想,蓝桥,include,day
From: https://blog.csdn.net/weixin_66385155/article/details/143815607

相关文章

  • AI|经常崩溃的问题解决
    AdobeIllustratorCrashes网络上大部分说法都是重装AI,兼容性问题,管理员权限或者是版本不对,经测试均无效,甚至出现重装系统这种离谱的办法,正确的解决办法是把首选项的性能里的GPU取消勾选,或者再把电脑的虚拟内存扩大即可。 Step1:打开首选项 Step2:取消勾选GPU性能......
  • 第十六届蓝桥杯嵌入式赛道备赛---ADC+DMA多通道读取(日志四)
    前言        ADC转换是一个比较简单的模块,但是其中有很多的细节问题需要处理到,这些问题也是我在写程序的时候遇到的。如果是用ADC+DMA,或者是ADC多通道,这些问题相信你也会遇到,接下来将详细展开讨论。    先来看一下开发板中为我们准备的对应资源---电位器。两......
  • CF987 Div2 F 题解
    阶段1考虑我们每次随机删除两个然后询问,若中位数为\(\frac{n}{2},\frac{n}{2}+1\)称被删除的两个为基准数,用\(v_1,v_2\)代表。每次询问得到解的概率约为\(\frac{1}{2}\)。发现基准数一定一个\(<\frac{n}{2}\)一个\(>\frac{n}{2}+1\),且对于一次四个数的询问\(x......
  • [AGC018C] Coins 题解
    先全部选\(a_i\),假设\(b_i=b_i-a_i,c_i=c_i-a_i\)。那么题目转化为选\(y\)个\(b\)和\(z\)个\(c\)使得答案最大。会发现若\(i\)位置选的\(b\),\(j\)位置选的\(c\),那么需要满足\(b_i-c_i>b_j-c_j\)。我们按上述条件排序,这样一定是在左边选\(b\),右边选\(c\)。那......
  • 题解:ABC013D 阿弥陀
    先考虑\(D=1\),明显可以\(O(M)\)模拟预处理出在最上面的每个位置往下走会走到什么位置,之后每次就可以\(O(1)\)查询了。当\(D>1\)时,可以依赖预处理的数据每次\(O(D)\)暴力查询。又注意到每次对所有位置进行的变换操作是一样的,可以倍增后用类似快速幂的方法优化到\(O(\log......
  • CF2031D 题解
    原题链接最后悔的一集,感觉D\(<\)everything。考虑由确定的点推出其他点的答案,发现最高点的答案是确定的,设其位置为\(x\)。然后根据题目定义,发现可以分成\([1,x-1],[x,n]\)两个区间,\([x,n]\)答案均为\(h_x\)。对于\([1,x-1]\)区间,我们找到第一个\(>[x,n]\)区间最小......
  • 读数据质量管理:数据可靠性与数据质量问题解决之道05数据标准化
    1. 批处理1.1. 批处理在一段时间内收集数据,然后将大量数据“批处理”在离散的数据包中1.2. 直到20世纪10年代中期,批处理都是处理分析型数据最常用的方法1.3. 批处理比流处理要便宜得多,即使是对时间要求最苛刻的处理需求也足以满足1.4. 批处理是经过时间考验的标准,并且仍......
  • POI 四题题解
    P3434[POI2006]KRA-TheDisks考场上不知道在想什么,把\(O(n)\)正解改成\(O(n\mathrm{log}n)\)的了。关于\(O(n\mathrm{log}n)\)做法很多,我只讲我的。直接二分盘子会在哪里卡住,二分范围是\(1\simlst\)。\(lst\)表示上一个盘子卡住的位置。\(\mathrm{Code}\)#includ......
  • CF1909F1 Small Permutation Problem (Easy Version) 题解
    CF1909F1SmallPermutationProblem(EasyVersion)题解直接莽做显然不好统计。考虑统计每一次\(i\)的变化有多少种方案数来匹配,也就是对\(a\)数组差分。考虑到对于\(a_i\),只有\([1,i]\)里的数会对\(a_i\)有影响。注意到\(p\)形成一个排列,于是我们不妨考虑此时\(p......
  • 中秋节赏月感想
    今年中秋节,天公不作美。一场突如其来的台风搅乱了原本宁复制全选翻译分享搜索传统佳节赏月的期待。台风过后,虽然云层还未完全散去,但月亮依旧顽强地透过缝隙,洒下斑驳陆离的银光。 站在宿舍的窗台边上,仰望着那轮努力穿透云隙的圆月,我不禁感慨万干。这月亮,不就像我们每个人的人生......