第十一届蓝桥杯大赛软件类省赛第二场

第十一届蓝桥杯省赛大学B组试题

A题 门牌制作

思路:

统计1到2020号门牌的字符2的总个数.

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int sum = 0;// 计数
    int a[4];// 存取个位 十位 百位 千位
    for(int i = 1; i <= 2020; i++)
    {
        a[0] = i % 10;
        a[1] = i % 100 / 10;
        a[2] = i % 1000 / 100;
        a[3] = i / 1000;

        for(int k = 3; k >= 0; k--)
        {
            if(a[k] == 2)
                sum++;
        }
    }
    cout << sum;
    return 0;
}

答案是 624

B题 跑步锻炼

image-20210321213902762
求解代码:

#include <bits/stdc++.h>
using namespace std;


int GCD(int a, int b)
{
    if(b == 0)
        return a;
    else
        return GCD(b, a%b);

}

int main()
{
    int sum = 0;
    for(int i = 1; i <= 2020; i++)
        for(int j = 1; j <= 2020; j++)
        {
            if(GCD(i,j) == 1)
                sum++;
        }

    cout << sum;

    return 0;
}

答案: 2481215

C题 蛇形填数

image-20210322104134170

思路:

image-20210322122226975

一般都会想到把对角线上的递推公式找出来,假设对角线上的元素都是\(a_n\)那么很明显每一个\(a_n\)都与\(n\)以及\(a_{n-1}\)有关系,并且应该是一次的.

其实此时可以推出来递推公式.

\[a_n = 4(n-1) + a_{n-1} \]

例如 \(a_4\) = 25 = \(4 \times 3 + 13\)

求解代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int a = 1;
    for(int i = 2; i <= 20; i++)
    {
        a = 4*(i-1) + a;
    }
    cout << a;
    return 0;
}

D题 跑步锻炼

image-20210322161512793

思路: 处理好每天天数的增加,月份年份增加,核心是day++,请参考代码注释.

#include <bits/stdc++.h>
using namespace std;

// 月份天数数组 先默认是平年
// M[0] 设置为0 是为了让月份和数组下标对应
int M[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

int main()
{
    int y = 2000, m = 1, d = 1, w = 6, ans = 0;
    while(y != 2020 || m != 10 || d != 1)
    {
        d++; // d++一定要放在前面,下面有解释
        w++;// 由于没先算第一天的 因此也要有 w++
        // 判断平年闰年
        if((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
            M[2] = 29;
        else
            M[2] = 28;

        w = w % 7; // 这样默认 0是周天 1是周一.....
        if(d > M[m])
        {
            d = 1;
            m++;
        }

        if(m > 12)
        {
            m = 1;
            y++;
        }

         //月初或者周一多加一天
        if(d == 1 || w == 1)
        {
            ans++;
        }
        ans++;

    }

    ans += 2; //加上第一天要跑2千米

    cout << ans;
    return 0;
}

为什么要把 d++, 放在while循环的前面的,这样的话岂不是相当于第一天的跑步里程没有加进去?所以放在while循环体的后面,岂不是更好??

答案是 不能放在后面,我们观察一下 while循环的结束条件,第11行,也就是当 y = 2020, m = 10, d = 1时循环终止.但是,循环终止的条件是在第 **24,25 **行达到的.image-20210325180513505,如果d++,在其下面的话,则恰好跳过了循环结束条件.d变成2了.

最终答案: 8879

E题 七段码

image-20210322210409199

  • 不正经解法

    我们知道,所有灯发光的情况一共有$C_71+C_72+C_73+C_74+C_75+C_76 +C_7^7 = 127 $种可能,我们可以人工判断.....所以我们想办法,让计算机来画一个这样的图案:

    image-20210326181415267

    具体细节请看代码:

// 全组合实现
// 关键字 栈 递归

#include <bits/stdc++.h>

using namespace std;

vector <int> s;
int count_numbers = 0;



// _
//|_|
//|_|


void draw_ejg(int i)
{
    if(i == 0)
        cout << " _\n";
    if(i == 1)
        cout << "|";
    if(i == 2)
        cout << "_";
    if(i == 3)
        cout << "|\n";
    if(i == 4)
        cout << "|";
    if(i == 5)
        cout << "_";
    if(i == 6)
        cout << "|\n";
}

void print(int n)
{
    if(count_numbers == 0)
    {
        count_numbers++;
        return;
    }
    count_numbers++;
    cout << count_numbers-1 << ":" << endl;
    // 利用子集数组,实现A的子集求解
    for(int i = 0; i < n; i++)
    {
         if(s[i] == 1)
        {
            draw_ejg(i);
        }
        else
        {
            if(i == 3 or i == 6)
                cout << "\n";
            else
                cout << " ";
        }
    }

    cout << endl << endl;
}

void subsetting(int c, int n)
{
    if(c <= n)
    {
        s.push_back(0);
        subsetting(c+1, n);
        s.pop_back();
        s.push_back(1);
        subsetting(c+1, n);
        s.pop_back();
    }
    else
        print(n);
}


int main()
{
    subsetting(1,7);

    return 0;
}

大家可以自行运行一下,,,然后就硬数,,,,,这是部分运行截图

image-20210326182439555

我们可以得到答案:

  • 正经解法

如果使用纯程序解法,其实也不难,创建连接矩阵,遍历查看点与点的连接情况.但我不会写.....


#include <bits/stdc++.h>

using namespace std;

vector <int> s;
vector <int> A;
int count_numbers = 127;

int flag = 0;

int adj[7][7] = {
{1,1,0,1,0,0,0},
{1,1,1,0,1,0,0},
{0,1,1,1,1,0,1},
{1,0,1,1,0,0,1},
{0,1,1,0,1,1,0},
{0,0,0,0,1,1,1},
{0,0,1,1,0,1,1}
};


void print(int n)
{
    for(int i = 0; i < n; i++)
    {
        if(s[i] == 1)
            A.push_back(i);
    }

    // print A
//    for(int i = 0; i < A.size(); i++)
//        cout << A[i];
//    cout << endl;



    A.clear();

}

void subsetting(int c, int n)
{
    if(c <= n)
    {
        s.push_back(0);
        subsetting(c+1, n);
        s.pop_back();
        s.push_back(1);
        subsetting(c+1, n);
        s.pop_back();
    }
    else
        print(n);
}


int main()
{
    cout << "hello world";
    return 0;
}

F题 成绩统计

image-20210330092824474
求解代码:


#include <bits/stdc++.h>

using namespace std;

int main()
{
    int exc = 0;
    int pass = 0;
    int score;
    int n;

    cin >> n;

    int flag = n;
    while(flag)
    {
        cin >> score;
        if(score >= 60)
            pass++;
        if(score >= 85)
            exc++;
        flag--;
    }

    double pass_ac = double(pass)/double(n);
    double exc_ac = double(exc)/double(n);

    printf("%.2f\n%.2f", pass_ac, exc_ac);

}

G题 回文日期

image-20210331210841614

求解代码:

#include <bits/stdc++.h>
using namespace std;

// 月份天数数组 先默认是平年
// M[0] 设置为0 是为了让月份和数组下标对应
int M[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};


bool judge1(int y, int m, int d)
{
    // 将 y m d 转化为一个数字
    long long date = y*10000 + m*100 + d;

    // 将这个数字转化为一个字符串
    stringstream s;
    s << date;
    string date_str;
    s >> date_str;

    for(int i = 0; i < date_str.length()/2; i++)
    {
        if(date_str[i] != date_str[date_str.length()-1-i])
            return 0;
    }

    cout << date_str << endl;
    return 1;
}

bool judge2(int y, int m, int d)
{
     // 将 y m d 转化为一个数字
    long long date = y*10000 + m*100 + d;

    // 将这个数字转化为一个字符串
    stringstream s;
    s << date;
    string date_str;
    s >> date_str;

    if(date_str[0] == date_str[2] && date_str[2] == date_str[5] && date_str[5] == date_str[7]
       && date_str[1] == date_str[3] && date_str[3] == date_str[4] && date_str[4] == date_str[6])
    {
        cout << date_str;
        return 1;
    }
    return 0;
}


int main()
{
    int flag1 = 0;
    int flag2 = 0;

    long long date;
    cin >> date;

    // 提取出 年 月 日


    int y = date / 10000;
    int m = date % 10000 / 100;
    int d = date % 100;


    while((!flag1) || (!flag2))
    {
        d++;
        // 判断平年闰年
        if((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
            M[2] = 29;
        else
            M[2] = 28;

        if(d > M[m])
        {
            d = 1;
            m++;
        }

        if(m > 12)
        {
            m = 1;
            y++;
        }

        if(!flag1)
            flag1 = judge1(y, m, d);
        if(!flag2)
            flag2 = judge2(y, m, d);

    }

    return 0;
}

H题 子串分值和

image-20210331211108919

#include <bits/stdc++.h>
using namespace std;


string str;


int f(int i,int j)
{
    int count_numbers = 0;
    int uni = 1;
    string flag = "";
    int flag2;
    string sub_str = str.substr(i,j+1);
    for(int i = 0; i < sub_str.length(); i++)
    {
        for(int j = 0; j < flag.length(); j++)
        {
            if(sub_str[i] == flag[j])
            {
                uni = 0;
                break;
            }
        }
        if(uni)
        {
            count_numbers++;
            flag += sub_str[i];
        }
    }
    return count_numbers;

}



int main()
{
    cin >> str;

    int sum = 0;
    for(int i = 0; i < str.length(); i++)
    {
        for(int j = i; j <  str.length(); j++)
            sum += f(i,j);
    }
    cout << sum;
    return 0;
}

I题 平面切分

image-20210406093824979

思路:对于一条直线,在它不是重边的前提下,如果与其它直线交点个数是0,则平面切分数加1,其次,与其它直线每产生一个不同的交点,则平面切分数又加1.

未完待续........

posted @ 2021-04-08 21:10  CuriosityWang  阅读(178)  评论(0编辑  收藏  举报