【蓝桥杯历年真题合集】蓝桥杯2020初赛

简介: 门牌制作小蓝要为一条街的住户制作门牌号。这条街一共有2020 位住户,门牌号从1 到2020 编号。小蓝制作门牌的方法是先制作0 到9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017 需要依次粘贴字符1、0、1、7,即需要1 个字符0,2 个字符1,1 个字符7。请问要制作所有的1 到2020 号门牌,总共需要多少个字符2?输出格式这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。#i.


 门牌制作

小蓝要为一条街的住户制作门牌号。

这条街一共有2020 位住户,门牌号从1 到2020 编号。

小蓝制作门牌的方法是先制作0 到9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017 需要依次粘贴字符1、0、1、7,即需要1 个字符0,2 个字符1,1 个字符7。

请问要制作所有的1 到2020 号门牌,总共需要多少个字符2?

输出格式

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

#include <iostream>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
typedef long long ll;
int main()
{
    int num = 0;
    for(int i = 1; i <= 2020; i ++)
    {
        if(i % 10 == 2) num ++;
        if(i / 10 % 10 == 2) num ++;
        if(i / 100 % 10 == 2) num ++;
        if(i / 1000 == 2) num ++;
    }
    cout << num;
    return 0;
}

image.gif

既约分数

如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。

例如\frac{3}{4},\frac{5}{2},\frac{1}{8},\frac{7}{1}43,25,81,17都是既约分数。

请问,有多少个既约分数,分子和分母都是1 到2020 之间的整数(包括1和2020)?

输出格式

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

image.png

#include <iostream>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
typedef long long ll;
int main()
{
    int x = 0;
      for(int i = 1; i <= 2020; i ++)
      {
          for(int j = 1; j <= 2020; j ++)
          {
              if(__gcd(i, j) == 1)
              {
                  x ++;
              }
          }
      }
      cout << x;
  return 0;
}

image.gif

蛇形填数

如下图所示,小明用从1 开始的正整数“蛇形”填充无限大的矩阵。

\begin{matrix} 1 & 2 & 6 & 7 & 15 & ... \\ 3 & 5 & 8 & 14 & ... \\ 4 & 9 & 13 & ... \\ 10 & 12 & ... \\ 11 & ... \\ ...   \end{matrix}1341011...  25912...6813...714...15......

容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20 行第20 列的数是多少?

输出格式

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

image.png

#include <iostream>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
int main()
{
    int s = 1;
    for(int i = 1; i < 20; i ++)
    {
        s += 4 * i;
    }
    printf("%d",s);
    return 0;
}

image.gifimage.png

 七段码

小蓝要用七段码数码管来表示一种特殊的文字。

image.png

上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。

小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。

例如:b 发光,其他二极管不发光可以用来表达一种字符。

例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。

例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。

例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。

请问,小蓝可以用七段码数码管表达多少种不同的字符?

输出格式

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。

#include <bits/stdc++.h>
using namespace std;
string str = "0000000";
string vis;
int ans = 0;
//如何检查排列是否合法?
int umap[7][7];
void initmap()
{
    memset(umap, 0, sizeof(umap));
    umap[0][1] = umap[0][5] = 1;
    umap[1][0] = umap[1][2] = umap[1][6] = 1;
    umap[2][1] = umap[2][3] = umap[2][6] = 1;
    umap[3][2] = umap[3][4] = 1;
    umap[4][3] = umap[4][5] = umap[4][6] = 1;
    umap[5][0] = umap[5][4] = umap[5][6] = 1;
    umap[6][1] = umap[6][2] = umap[6][4] = umap[6][5] = 1;
}
void dfs(int curr)
{
    vis[curr] = '0';//标记访问过了
    for (int j = 0; j < 7; ++j)
    {
        if (umap[curr][j] == 1 && vis[j] == '1')
            dfs(j);
    }
}
bool check()
{
    int cnt = 0;
    for (int i = 0; i < 7;++i)
    {
        if(vis[i]=='1')
        {
            dfs(i);
            ++cnt;
        }
    }
    return cnt == 1;
}
int main()
{
    initmap();
    for (int i = 0; i < 7; ++i)
    {
        sort(str.begin(), str.end());
        str[6 - i] = '1';
        do
        {
            vis = str;
            if(check())
                ++ans;
        } while (next_permutation(str.begin(), str.end()));
    }
    cout << ans << endl;
    return 0;
}

image.gif

跑步锻炼

小蓝每天都锻炼身体。

正常情况下,小蓝每天跑1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑2 千米。如果同时是周一或月初,小蓝也是跑2 千米。

小蓝跑步已经坚持了很长时间,从2000 年1 月1 日周六(含)到2020 年10 月1 日周四(含)。

请问这段时间小蓝总共跑步多少千米?


这是一道结果填空的题,你只需要算出结果后提交即可。

本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int ans=0;
    int mon = 6;
    int monthes[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(int i = 2000; i <= 2020; i ++)
    {
        if((i%4==0&&i%100!=0)||(i%400==0))
            monthes[2]=29;
        else
            monthes[2]=28;
        for(int month = 1; month <= 12; month ++)
        {
            for(int day = 1; day <= monthes[month]; day ++)
            {
                ans ++;
                if(mon == 8)
                    mon = 1;
                if(mon == 1 || day == 1)
                ans ++;
                mon ++;
            if(i == 2020 && month == 10 && day == 1)//截至日期输出
                printf("%d",ans);
            }
        }
    }
    return 0;
}

image.gif

 回文日期

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年2 月2日。因为如果将这个日期按“yyyymmdd” 的格式写成一个8 位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。

有人表示20200202 是“千年一遇” 的特殊日子。对此小明很不认同,因为不到2 年之后就是下一个回文日期:20211202 即2021 年12 月2 日。

也有人表示20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同,因为大约100 年后就能遇到下一个ABABBABA 型的回文日期:21211212 即2121 年12 月12 日。算不上“千年一遇”,顶多算“千年两遇”。

给定一个8 位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA 型的回文日期各是哪一天。

输入格式

输入包含多组测试数据,第一行为正整数T。(T≤1000)

接下来T行,每行包含一个八位整数N,表示日期。

对于所有评测用例,10000101 ≤ N ≤ 89991231,保证N 是一个合法日期的8 位数表示。

输出格式

对于每组测试数据输出两行,每行1 个八位数。

第一行表示下一个回文日期,第二行表示下一个ABABBABA 型的回文日期。

输入样例

2
20200202
20211203

image.gif

输出样例

20211202
21211212
20300302
21211212

image.gif

#include <iostream>
using namespace std;
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y, int m, int d) 
{
    if (d <= 0 || m <= 0 || m >= 13) return false;
    if (m != 2) 
    {
        if (d > months[m]) return false;
    }
    else
    {
        int days = months[2] + (y % 4 == 0 && y % 100 != 0 || y % 400 == 0);
        if (d > days) return false;
    }
    return true;
}
int flip(int x)
{
    int res = 0;
    while (x)
    {
        res = res * 10 + x % 10;
        x /= 10;
    }
    return res;
}
bool st1, st2;
int ans1, ans2;
int main()
{
    int n;
    cin >> n;
    for (int i = n + 1; i <= 89991231; i++)
    {
        int year = i / 10000, month = i % 10000 / 100, day = i % 100;
        if (check(year, month, day))
        {
            if (i % 10000 == flip(year) && !st1) 
                st1 = true, ans1 = i;
            if (i % 10000 == flip(year) && (month / 10 == day / 10) && (month % 10 == day % 10) && !st2) 
                st2 = true, ans2 = i;
        }
        if (st1 && st2) break;
    }
    printf("%d\n%d\n", ans1, ans2);
    return 0;
}

image.gif

字串排序

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。

在冒泡排序中,每次只能交换相邻的两个元素。

小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。

例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。

小蓝的幸运数字是V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V 次交换。请帮助小蓝找一个这样的字符串。

如果可能找到多个,请告诉小蓝最短的那个。

如果最短的仍然有多个,请告诉小蓝字典序最小的那个。

请注意字符串中可以包含相同的字符。

输入格式

输入第一行为T,表示存在T组测试数据。(T≤25)

对于每组测试数据,输入一行包含一个整数V,为小蓝的幸运数字。

对于所有评测用例,1 ≤ V ≤ 10000。

输出格式

每组测试数据,输出一个字符串,为所求的答案。

输入样例

2
4
100

image.gif

输出样例

bbaa
jihgfeeddccbbaa

image.gif

#include<bits/stdc++.h>
using namespace std;
int V , len , now , cnt[27] , sum[27];
int get_max(int len){
    return ((len - (len / 26 + 1)) * (len / 26 + 1) * (len % 26) + (26 - len % 26) * (len / 26) * (len - len / 26)) / 2;
}
bool check(int x , int n){
    memset(cnt , 0 , sizeof(cnt));
    int add1 = 0 , add2 = 0;
    for(int j = 26 ; j >= x + 1 ; j --) add1 += sum[j];
    sum[x] ++ ;
    for(int L = 1 ; L <= n ; L ++){
        int ma = -1 , pos = 0 , num = 0;
        for(int j = 26 ; j >= 1 ; j --){
            if(L - 1 - cnt[j] + num > ma){
                ma = L - 1 - cnt[j] + num;
                pos = j;
            }
            num += sum[j];
        }
        add2 += ma , cnt[pos] ++;
    }
    if(now + add1 + add2 >= V) {
        now += add1;
        return true;
    }
    else {
        sum[x] -- ;
        return false;
    }
}
signed main()
{
    string ans = "";
    cin >> V;
    for(int i = 1 ; ; i ++) {
        if(get_max(i) >= V){
            len = i;
            break ;
        }
    }
    for(int i = 1 ; i <= len ; i ++){
        for(int j = 1 ; j <= 26 ; j ++){
            if(check(j , len - i)){
                ans += char(j + 'a' - 1);
                break ;
            }
        }
    }
    cout << ans << '\n';
    return 0;
}

image.gif

 成绩统计

小蓝给学生们组织了一场考试,卷面总分为100 分,每个学生的得分都是一个0 到100 的整数。

如果得分至少是60 分,则称为及格。如果得分至少为85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。

输入格式

输入的第一行包含一个整数n,表示考试人数。

接下来n 行,每行包含一个0 至100 的整数,表示一个学生的得分。

输出格式

输出两行,每行一个百分数,分别表示及格率和优秀率。

百分号前的部分四舍五入保留整数。

输入样例

7
80
92
56
74
88
100
0

image.gif

输出样例

71%
43%

image.gif

#include <iostream>
#include <bits/stdc++.h>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <bitset>
using namespace std;
typedef long long ll;
int main()
{
    int n, jige = 0, youxiu = 0;
    cin >> n;
    int m = n;
    while(n --)
    {
        int a;
        cin >> a;
        if(a >= 60)
            jige ++;
        if(a >= 85)
            youxiu ++;
    }
    double sum1 = jige * 1.00 / m * 100;
    double sum2 = youxiu * 1.00 / m * 100;
    printf("%.0lf%\n%.0lf%\n",sum1, sum2);
    return 0;
}

image.gif

子串分值和

对于一个字符串S ,我们定义S 的分值f (S ) 为S 中出现的不同的字符个数。

例如f (”aba”) = 2, f (”abc”) = 3, f (”aaa”) = 1。

现在给定一个字符串S [0 : n - 1](长度为n),请你计算对于所有S 的非空子串S [i : j](0 ≤ i ≤ j < n), f (S [i:: j]) 的和是多少。

输入格式

输入一行包含一个由小写字母组成的字符串S 。

对于所有评测用例,1 ≤ n ≤ 100000。

输出格式

输出一个整数表示答案。

输入样例

ababc

image.gif

输出样例

28

image.gif

#include <iostream>
#include<cstring>
using namespace std;
typedef long long ll;
int main()
{
    string s;
    cin >> s;
    ll total = 0;
    int a[26];
    memset(a,-1,sizeof(a)); 
    a[s[0] - 'a'] = 0;
    total += s.size(); 
    for(int i=1;i<s.size();i++)
    {
        total += (i - a[s[i] - 'a']) * (s.size() - i);
        a[s[i] - 'a'] = i;
    }
    cout << total;
  return 0;
}

image.gif

相关文章
|
7月前
|
传感器
蓝桥杯历年真题题解----2020年-- 子串分值和
蓝桥杯历年真题题解----2020年-- 子串分值和
|
搜索推荐
蓝桥杯历年真题题解----2020年-- 排序
蓝桥杯历年真题题解----2020年-- 排序
下一篇
DataWorks