【传智杯】儒略历、评委打分、萝卜数据库题解
🍎 博客主页:🌙@披星戴月的贾维斯
🍎 欢迎关注:👍点赞🍃收藏🔥留言
🍇系列专栏:🌙 蓝桥杯
🌙请不要相信胜利就像山坡上的蒲公英一样唾手可得,但是请相信,世界上总有一些美好值得我们全力以赴,哪怕粉身碎骨!🌙
🍉一起加油,去追寻、去成为更好的自己!
文章目录
- 🍎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++代码示例
#include<bits/stdc++.h>
using 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 < date.size(); i++)
{
if(date[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 < y ; i++)
{
if(check(i)) r++;
}
r += 2; //这里会少2天,要加上
}
if(check(y) && m > 2)r++;
ans += r;
cout << ans << endl;
return 0;
}
🍎2、[传智杯 #3 练习赛] 评委打分
题目描述
小 A 参加一个综艺节目。一共有 n ( 3 ≤ n ≤ 1 0 6 ) n(3 \le n \le 10^6) n(3≤n≤106) 名评委参与打分(分数范围是 0 到 100 的整数),每个评委依次亮出自己的得分。
为了节目效果,要求从第三个评委开始,每当第 i i i 个评委给出打分后,立刻计算出出这个选手在前 i i i 名评委的打分中,去掉一个最高分和一个最低分,剩下 i − 2 i-2 i−2 个评委的平均分,保留 2 2 2 位小数。
输入格式
第一行输入一个整数 n n n,表示评委人数。
第二行输出 n n n 个整数,表示各个评委的打分。
输出格式
输出共 n − 2 n-2 n−2 行,每行表示对应的答案。
样例 #1
样例输入 #1
6
11 45 14 19 19 81
样例输出 #1
14.00
16.50
17.33
24.25
分析题意:
这道题比较简单,就是让我们求第三个评委开始,每当后面的评委打分,给出题目想要的结果,但是这道题会卡输入,我们如果是用CIn输入的话,最好写一下快读模板。
C++代码示例
#include<bits/stdc++.h>
using 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<=n; i++)
{
double x;
cin >> 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(1≤k≤100) 个字段,每个字段名都是整数,里面存储的数值也都是整数。
现在你支持如下操作:
-
向数据库中插入一个记录,它可能只会包含 k k k 个字段的某一部分。具体的操作格式详见“输入格式”。
-
在数据库中查询有多少条符合条件的记录。
现在你总共有 n n n 次操作( 1 ≤ n ≤ 1000 1 \;\leq n \leq 1000 1≤n≤1000),请你对每个回答操作,输出结果。
输入格式
第一行两个整数 n , k n,k n,k ,意义如题所述。
接下来的若干行,每行代表一次操作,具体如下:
-
1 p x 1 y 1 , . . . , x p y p 1\ p\ x_1\ \ y_1,...,x_p\ y_p 1 p x1 y1,...,xp yp :表示一个插入操作,其中共有 p p p 个字段,第 i i i 字段的名字是 x i x_i xi ,值为 y i y_i yi .此处我们保证 1 ≤ x i ≤ k , 1 ≤ y i ≤ 1000 1 \leq x_i \leq k, 1\leq y_i \leq 1000 1≤xi≤k,1≤yi≤1000,并且 x i , y i x_i,y_i xi,yi 均为整数。
-
2 x y m i n y m a x 2\ x\ y_{min}\ y_{max} 2 x ymin ymax:表示一次查询操作,表示查询所有满足 字段 x x x 的值在 [ y m i n , y m a x ] [y_{min},y_{max}] [ymin,ymax] 之间的记录有多少个。
输出格式
对于每个查询操作,输出一行一个整数,表示符合条件的记录个数。
样例 #1
样例输入 #1
4 5
1 2 1 2 2 4
2 2 1 5
1 2 3 5 4 6
2 4 7 8
样例输出 #1
1
0
分析题意:
这道题是考模拟,模拟题目的要求,从而求出答案。我们通过读题可以知道这道题是求我们向(数据库)里插入一些数,然后给询问,问符合某一区间的数有几个,所以对样例1,有4次操作,数据库支持5个字段, 接下来n行,第一行第一个数是1,说明是插入,接下来是表示有两个字段,表示字段1的值是2,字段2的值是4,接下来一行开头是2,表示是查询 字段2在1到5之间的有几个…
所以,我们需要有两个数组,一个存字段号,另一个存值。
C++代码示例:
#include<bits/stdc++.h>
using 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 <= t; i++)
{
cin >> 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 < num1; i++)
if(a[i] == t)
if(b[i] >= l && b[i] <= r) ans++;
cout << ans << endl;
}
}
return 0;
}
🍎总结
这次和大家分享了传智杯的几题普及/普及+难度的题,希望大家读后能有所收获!