博客主页:@披星戴月的贾维斯
欢迎关注:点赞收藏留言
系列专栏: 蓝桥杯
请不要相信胜利就像山坡上的蒲公英一样唾手可得,但是请相信,世界上总有一些美好值得我们全力以赴,哪怕粉身碎骨!
一起加油,去追寻、去成为更好的自己!

文章目录

  • 1、# [传智杯 #3 练习赛] 儒略历
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 样例 #2
      • 样例输入 #2
      • 样例输出 #2
    • 样例 #3
      • 样例输入 #3
      • 样例输出 #3
    • 样例 #4
      • 样例输入 #4
      • 样例输出 #4
      • 分析题意:
  • 2、[传智杯 #3 练习赛] 评委打分
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
      • 分析题意:
  • 3、 [传智杯 #4 初赛] 萝卜数据库
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
      • 分析题意:
  • 总结

提示:以下是本篇文章正文内容,下面案例可供参考


这次我们继续和大家分享一些传智杯题解,多刷题对我们来说是一件非常重要的事,坚持下去会有很多收获!

1、# [传智杯 #3 练习赛] 儒略历

题目描述

在 1582 年之前,以 4 为倍数的年份为闰年。正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 天。如果这年是闰年,那么二月则有 29 天。

但某位教皇发现这么做其实不够准确,会造成误差,因此规定从 1582 年开始,以 4 为倍数的年份,除了以 100 为倍数且不为 400 的倍数年份,才是闰年。同时为了消除误差,规定 1582 年 10 月 4 日的下一天是 1582 年 10 月 15 日,中间的日期就当作不存在了。

现在给出日期,计算这个日期到公元 1 年 1 月 1 日经过的天数。

输入格式

按照 日月年 的格式输入数据,其中日是 1 到 31 之间的整数,月是三个大写字母,年是 1 到 9999 之间的整数。保证这个日期是合法且存在的。

月份的大写字母:

  • 1月:JAN
  • 2月:FEB
  • 3月:MAR
  • 4月:APR
  • 5月:MAY
  • 6月:JUN
  • 7月:JUL
  • 8月:AUG
  • 9月:SEP
  • 10月:OCT
  • 11月:NOV
  • 12月:DEC

输出格式

输出一个整数表示答案

样例 #1

样例输入 #1

1JAN1

样例输出 #1

0

样例 #2

样例输入 #2

4OCT1582

样例输出 #2

577736

样例 #3

样例输入 #3

15OCT1582

样例输出 #3

577737

样例 #4

样例输入 #4

21NOV2020

样例输出 #4

737751

分析题意:

当初第一眼看到题目的时候,发现题目挺长的,不容易读,后面发现这题的考点是日期,觉得不会很难,但是后面发现写起来并不容易,也调试了好久。首先,在读入数据部分,我们要建立英文月份和数字月份的对应关系,而且读入没有空格,所以输入类型应该是string类型,然后我们再来分割年,月,日。而且由于题目是求经过的天数,我们最好建立一个月份对应的累计天数,比如4月对应1,2,3,4月的天数累计,这样的数组,还要有判断是否是闰年的check函数,还要特判1582 年10月4日以前的天数。来看看代码是如何实现的吧!
C++代码示例

#includeusing namespace std;typedef long long ll;const int N = 1e5 + 10;string tg[15] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL","AUG","SEP", "OCT", "NOV", "DEC"};int a[15] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273,304, 334,365 };bool check1(int x) //1582年前判断闰年的方式{if(x % 4 == 0) return true;else return false;}bool check(int x){if(x % 4 == 0 && x % 100 != 0 || x % 400 == 0) return true;else return false;}int main (){string date; //把时间一次性先读入进去cin >> date;string day, month, year;if(date[1] > '9')//说明它的日期是10天以内的{day += date[0];month += date[1];month += date[2];month += date[3];}else {day += date[0];day += date[1];month += date[2];month += date[3];month += date[4];}//求年份比较简单for(int i = 3; i '0' && date[i] <= '9')year += date[i];}int m = 0, y = 0, d = 0;for(int i = 0; i < 15; i++){if(month == tg[i]){m = i;//寻找月份的映射关系break;}}y = stoi(year);d = stoi(day);int ans = 0, r = 0;//ans 是最后的结果,r是还要加的数ans += (y - 1 ) * 365;ans += d - 1;ans += a[m - 1];if(y < 1582 || y == 1582 && m < 10 || y== 1582 && m == 10 || d <= 4){for(int i = 1; i < y; i++){if(check1(i)) r++;}//1582年前判断闰年的方式}else{for(int i = 1; i  2)r++;ans += r;cout << ans << endl;return 0;}

2、[传智杯 #3 练习赛] 评委打分

题目描述

小 A 参加一个综艺节目。一共有 n ( 3 ≤ n ≤ 1 06)n(3 \le n \le 10^6)n(3n106) 名评委参与打分(分数范围是 0 到 100 的整数),每个评委依次亮出自己的得分。

为了节目效果,要求从第三个评委开始,每当第 iii 个评委给出打分后,立刻计算出出这个选手在前 iii 名评委的打分中,去掉一个最高分和一个最低分,剩下 i − 2i-2i2 个评委的平均分,保留 222 位小数。

输入格式

第一行输入一个整数 nnn,表示评委人数。

第二行输出 nnn 个整数,表示各个评委的打分。

输出格式

输出共 n − 2n-2n2 行,每行表示对应的答案。

样例 #1

样例输入 #1

611 45 14 19 19 81

样例输出 #1

14.0016.5017.3324.25

分析题意:

这道题比较简单,就是让我们求第三个评委开始,每当后面的评委打分,给出题目想要的结果,但是这道题会卡输入,我们如果是用CIn输入的话,最好写一下快读模板。
C++代码示例

#includeusing namespace std;double ma= 0, mi = 110; //设置比较的最大和最小值double sum;int n;int main (){//C++关流ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);cin >> n;for(int i = 1; i> x;ma = max(ma, x);mi = min(mi, x);sum += x;if(i >= 3){ printf("%.2lf\n",(sum-ma-mi)/(i-2));}}return 0;}

3、 [传智杯 #4 初赛] 萝卜数据库

题目描述

花栗鼠很喜欢偷吃生产队的大萝卜,因此花栗鼠科技大学正在研究一种新型的数据库,叫做萝卜数据库。

具体来说,它支持 k ( 1 ≤ k ≤ 100 )k(1 \leq k \leq 100)k(1k100) 个字段,每个字段名都是整数,里面存储的数值也都是整数。

现在你支持如下操作:

  • 向数据库中插入一个记录,它可能只会包含 kkk 个字段的某一部分。具体的操作格式详见“输入格式”。

  • 在数据库中查询有多少条符合条件的记录。

现在你总共有 nnn 次操作( 1   ≤ n ≤ 10001 \;\leq n \leq 10001n1000),请你对每个回答操作,输出结果。

输入格式

第一行两个整数 n , kn,kn,k ,意义如题所述。

接下来的若干行,每行代表一次操作,具体如下:

  • 1px1 y1, . . . , xp yp 1\ p\ x_1\ \ y_1,…,x_p\ y_p1px1y1,,xpyp :表示一个插入操作,其中共有 ppp 个字段,第 iii 字段的名字是 xi x_ixi ,值为 yi y_iyi .此处我们保证 1 ≤ xi≤ k , 1 ≤ yi≤ 10001 \leq x_i \leq k, 1\leq y_i \leq 10001xik,1yi1000,并且 xi, yi x_i,y_ixi,yi 均为整数。

  • 2xy m i n y m a x 2\ x\ y_{min}\ y_{max}2xyminymax:表示一次查询操作,表示查询所有满足 字段 xxx 的值在 [ y m i n, y m a x][y_{min},y_{max}][ymin,ymax] 之间的记录有多少个。

输出格式

对于每个查询操作,输出一行一个整数,表示符合条件的记录个数。

样例 #1

样例输入 #1

4 51 2 1 2 2 42 2 1 51 2 3 5 4 62 4 7 8

样例输出 #1

10

分析题意:

这道题是考模拟,模拟题目的要求,从而求出答案。我们通过读题可以知道这道题是求我们向(数据库)里插入一些数,然后给询问,问符合某一区间的数有几个,所以对样例1,有4次操作,数据库支持5个字段, 接下来n行,第一行第一个数是1,说明是插入,接下来是表示有两个字段,表示字段1的值是2,字段2的值是4,接下来一行开头是2,表示是查询 字段2在1到5之间的有几个…
所以,我们需要有两个数组,一个存字段号,另一个存值。
C++代码示例:

#includeusing namespace std;const int N = 1e6 + 10;int n, k;int a[N], b[N]; //一个存字段号,一个存值int c, y, d, m;int num1, num2;int main (){cin >> n >> k;while(n --){int op, t;cin >> op;if(op == 1) //表示插入{cin >> t; //表示要插入的组数for(int i = 1; i > c >> d; //c 表示字段号,d表示值a[num1++] = c;b[num2++] = d;}}else//查询{int ans = 0;int l, r;cin >> t >> l >> r;for(int i = 0; i = l && b[i] <= r) ans++;cout << ans << endl;}}return 0;}

总结

这次和大家分享了传智杯的几题普及/普及+难度的题,希望大家读后能有所收获!