【传智杯】儒略历、评委打分、萝卜数据库题解

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

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


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

🍎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(3n106) 名评委参与打分(分数范围是 0 到 100 的整数),每个评委依次亮出自己的得分。

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

输入格式

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

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

输出格式

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

样例 #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(1k100) 个字段,每个字段名都是整数,里面存储的数值也都是整数。

现在你支持如下操作:

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

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

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

输入格式

第一行两个整数 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 1xik,1yi1000,并且 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;
}

🍎总结

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

  • 64
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 31
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

披星戴月的贾维斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值