第三届“传智杯”全国大学生IT技能大赛(练习赛题解)

比赛连接

各数字之和

第三届“传智杯”全国大学生IT技能大赛(练习赛题解)_第1张图片

思路

对数字进行拆分即可。

AC代码

#include
using namespace std;
bool check(int n) {
     
    int res = 0;
    while(n) {
     
        res += n % 10;
        n /= 10;
    }
    return res == 9 ? 1 : 0;
}
void solve(){
     
	int n, ans = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
     
        if (check(i)) {
     
            ans++;
            //printf("%d ", i);
        }
	}
	printf("%d\n", ans);
}
int main(){
     
	solve();
	return 0;
}

直角三角形

第三届“传智杯”全国大学生IT技能大赛(练习赛题解)_第2张图片

思路

我们知道勾股定理是a² + b² = c²,那么b = sqrt(c² - a²); 然后枚举a,算出b,再用勾股定理算两次的值是否相等即可。

AC代码

#include
#include
using namespace std;
void solve(){
     
	int c;
	scanf("%d", &c);
	for (int a = 1; a <= c; ++a) {
     
        int b = sqrt(c * c - a * a);
        if (b * b + a * a == c * c) {
     
            printf("%d %d\n", a, b);
            return;
        }
	}
}
int main(){
     
	solve();
	return 0;
}

单位转换

第三届“传智杯”全国大学生IT技能大赛(练习赛题解)_第3张图片

思路

简单模拟题:找出换算前的值,换算前的单位,换算后的单位,模拟求即可。

AC代码

#include
#include
#include
#include
#include
using namespace std;
void solve() {
     
    string s;
    cin >> s;
    char F, E;
    double sum = 0;
    for (int i = 0; i < s.size(); ++i) {
     
        if (s[i] < '0' || s[i] > '9') {
     
            F = s[i];
            break;
        } else {
     
            sum = sum * 10 + s[i] - '0';
        }
    }
    for (int i = 0; i < s.size(); ++i) {
     
        if (s[i] == '?') {
     
            E = s[i + 1];
            break;
        }
    }
    if (F == 'G' && E == 'G') {
     
        printf("%f\n", sum);
    } else if (F == 'G' && E == 'M'){
     
        printf("%f\n", sum * pow(2, 10));
    } else if (F == 'G' && E == 'K') {
     
        printf("%f\n", sum * pow(2, 20));
    } else if (F == 'G' && E == 'B') {
     
        printf("%f\n", sum * pow(2, 30));
    } else if (F == 'M' && E == 'G'){
     
        printf("%f\n", sum / pow(2, 10));
    } else if (F == 'M' && E == 'M') {
     
        printf("%f\n", sum);
    } else if (F == 'M' && E == 'K') {
     
        printf("%f\n", sum * pow(2, 10));
    } else if (F == 'M' && E == 'B'){
     
        printf("%f\n", sum * pow(2, 20));
    } else if (F == 'K' && E == 'G') {
     
        printf("%f\n", sum / pow(2, 20));
    } else if (F == 'K' && E == 'M') {
     
        printf("%f\n", sum / pow(2, 10));
    } else if (F == 'K' && E == 'K'){
     
        printf("%f\n", sum);
    } else if (F == 'K' && E == 'B') {
     
        printf("%f\n", sum * pow(2, 10));
    } else if (F == 'B' && E == 'G') {
     
        printf("%f\n", sum / pow(2, 30));
    } else if (F == 'B' && E == 'M'){
     
        printf("%f\n", sum / pow(2, 20));
    } else if (F == 'B' && E == 'K') {
     
        printf("%f\n", sum / pow(2, 10));
    } else if (F == 'B' && E == 'B') {
     
        printf("%f\n", sum);
    }
}
int main() {
     
    solve();
    return 0;
}

评委打分

第三届“传智杯”全国大学生IT技能大赛(练习赛题解)_第4张图片

思路

前缀和 + 记录最大最小值,先记录前缀和,然后去求平均分的时候,先去更新最大最小值即可。
打比赛这个题写复杂了,写了个线段树求区间最值,后来跟队友交流才知道这个题不需要那么麻烦,线段树区间最值代码就不发出来了。

AC代码

#include
#include
#include
using namespace std;
const int maxn = 1e6 + 5;
int sum[maxn], a[maxn];
void solve(){
     
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
     
        scanf("%d", &a[i]);
        sum[i] = sum[i - 1] + a[i];
	}
	int mx = max(a[1], a[2]), mi = min(a[1], a[2]);
	for (int i = 3; i <= n; ++i) {
     
        mx = max(mx, a[i]);
        mi = min(mi, a[i]);
        printf("%.2f\n", 1.0 * (sum[i] - mx - mi) / (i - 2));
	}
}
int main(){
     
	solve();
	return 0;
}

儒略历

题目描述:略

思路

首先我们拿到的是一串有天数,月份(英文), 年的字符串。分别把这天数,月份,和年份找出来。题目告诉的是月份的英文字母,我们就用map映射关系来找。然后直接从1年1月1日加到输入的年份即可,注意题目中有连个限制条件:
1.规定 1582 年 10 月 4 日的下一天是 1582 年 10 月 15 日,中间的日期就当作不存在了。判断日期是否在此中间即可,如果在就不加。
2.在 1582 年之前,以 4 为倍数的年份为闰年。因此规定从 1582 年开始,以 4 为倍数的年份,除了以 100 为倍数且不为 400 的倍数年份,才是闰年。

AC代码

#include
#include
#include
#include
#include
#include
using namespace std;
map<string, int> mp;
int mouths[13][2] ={
     {
     0, 0}, {
     31, 31}, {
     28, 29}, {
     31, 31}, {
     30, 30}, {
     31, 31}, {
     30, 30}, {
     31, 31}, {
     31, 31}, {
     30, 30}, {
     31, 31}, {
     30, 30}, {
     31, 31}};
bool isYears(int y) {
     
    if (y >= 1582)  return (y % 4 == 0 && y % 100) || y % 400 == 0;
    return y % 4 == 0;
}
void init() {
     
    mp["JAN"] = 1;
    mp["FEB"] = 2;
    mp["MAR"] = 3;
    mp["APR"] = 4;
    mp["MAY"] = 5;
    mp["JUN"] = 6;
    mp["JUL"] = 7;
    mp["AUG"] = 8;
    mp["SEP"] = 9;
    mp["OCT"] = 10;
    mp["NOV"] = 11;
    mp["DEC"] = 12;
}
void solve(){
     
    init();
	string s, mouth = "";
	cin >> s;
	int my = 0, mm, md = 0, dy = 1, dm = 1, dd = 1;
	for (int i = 0; i < s.size(); ++i) {
     
        if (md == 0) {
     
            while(s[i] <= '9' && s[i] >= '0') {
     
                md = md * 10 + s[i] - '0';
                ++i;
            }
        } else if (my == 0) {
     
            while(s[i] <= '9' && s[i] >= '0') {
     
                my = my * 10 + s[i] - '0';
                ++i;
            }
        }
        if (s[i] >= 'A' && s[i] <= 'Z') {
     
            mouth += s[i];
        }
	}
	mm = mp[mouth];
	int ans = 0;
	while (!(dy == my && dm == mm && dd == md)) {
     
        dd++;
        if (dy != 1582 || dm != 10 || (dd >= 15 || dd <= 4)) {
     
            ans++;
        }
        if (dd == mouths[dm][isYears(dy)] + 1) {
     
            dd = 1;
            dm++;
            if (dm == 13) {
     
                dm = 1;
                dy++;}
        }
	}
    cout << ans;
}
int main(){
     
	solve();
	return 0;
}

总结

这次比赛的题目很像蓝桥杯的填空题,例如勾股定理蓝桥杯省赛B组考过,第一题各位数拆分是填空题第一题经常考的,最后一个年份的题也是填空题经常考的。
稍微改改题目描述就和蓝桥杯类似了。例如

  1. 请你计算从 1 到 2020 的所有正整数中,有多少个数字的各位数和是 9?
  2. 请你计算从公元1年1月1日到2020年1月1日,一共有多少天?

你可能感兴趣的:(比赛)