第十一届蓝桥杯题解(部分)

第十一届蓝桥杯题解

注释:这段时间正好在写蓝桥杯的题,将部分的题目的解法和大家分享,代码中的网址是该代码蒟蒻当时参考其他大佬的题解文章所在的网址,鸣谢大佬,如有错误,欢迎各位大佬指正
有部分网址是提交答案的oj传送门

门牌制作

直接枚举即可

#include <bits/stdc++.h>
using namespace std;
// 传送门:http://oj.ecustacm.cn/problem.php?id=1508
int find(int n)
{
    int a=0;
    while(n)
    {
        if(n%10==2)
            a++;
        n/=10;
    }
    return a;
}
int main()
{
    long long ans=0;
    for(int i=1;i<=2020;i++)
    {
        ans+=find(i);
    }
    cout<<ans;
    return 0;
}

既约分数

直接从头开始枚举即可

#include <bits/stdc++.h>
using namespace std;
int gcd(int x,int y)
{
	if(y!=0)
		return gcd(y,x%y);
	else
		return x;
}
int main()
{
	long long ans=0;
	for(int i=1;i<=2020;i++)
		for(int j=1;j<=2020;j++)
			if(gcd(i,j)==1)
				ans++;
	cout<<ans;
	return 0;
}

蛇形填数

一道很经典的题,很多oj上都有的练习题

#include <bits/stdc++.h>
using namespace std;
// http://oj.ecustacm.cn/problem.php?id=1510
int main()
{
    int ans=1;

    for(int i=1;i<=19;i++)
        ans+=(i*4);
    cout<<ans;
    return 0;
}

或者直接用数学公式计算,算出通项公式

#include <bits/stdc++.h>
using namespace std;
// 规律:设a(n)是n行h列的元素, a(n)-a(n-1)=4*(n-1)
// a(n)=2*n*(n-1)+1
int main()
{
	cout<<2*20*19+1;
	return 0;
}

七段码

一道深搜回溯问题,首先用dfs(1)到dfs(7)利用回溯多层递归将所有的点亮方式枚举,然后在dfs(8)中对每一层的不同种情况进行judge判断即可
实质上是之前的递归将所有的可能情况进行罗列,在最后一层递归中进行判断

#include <bits/stdc++.h>
using namespace std;
// 传送门:http://oj.ecustacm.cn/problem.php?id=1511
// dfs+并查集+回溯
// 思路:首先用dfs(1)到dfs(7)利用回溯多层递归将所有的点亮方式枚举
// 然后在dfs(8)中对每一层的不同种情况进行judge判断即可
int edge[8][8];
int father[8]; //并查集数组
int use[8];    //判断是否点亮
void input()
{
    edge[1][2] = edge[1][6] = 1;
    edge[2][1] = edge[2][7] = edge[2][3] = 1;
    edge[3][2] = edge[3][4] = edge[3][7] = 1;
    edge[4][3] = edge[4][5] = 1;
    edge[5][4] = edge[5][6] = edge[5][7] = 1;
    edge[6][1] = edge[6][5] = edge[6][7] = 1;
}
int find(int x)
{
    if (father[x] == x)
        return x;
    else
        return father[x] = find(father[x]);
}
void connect(int x, int y)
{
    father[find(x)] = father[find(y)];
}
int ans;
void judge()
{
    for (int i = 1; i <= 7; i++)
        father[i] = i;
    for (int i = 1; i <= 7; i++)
        for (int j = 1; j <= 7; j++)
        {
            if (edge[i][j] && use[i] && use[j])
            {
                int fa1 = find(i);
                int fa2 = find(j);
                if (fa1 != fa2)
                {
                    connect(fa1, fa2);
                }
            }
        }
    int count = 0;
    for (int i = 1; i <= 7; i++)
    {
        if (use[i] && father[i] == i)
            count++;
    }//将所有的亮灯都连起来,看看是不是相连
    if (count == 1)
        ans++;
    return;
}
void dfs(int n)
{
    if (n > 7)
    {
        judge();
        return;
    }
    use[n] = 1;
    dfs(n + 1);
    use[n] = 0;
    dfs(n + 1); //回溯!
}
int main()
{
    input();
    dfs(1);
    cout << ans;
    return 0;
}

回文数日期

呃,用了内置的函数,在c语言网上是ac的,但是蓝桥杯的官网直接编译错误,可能是蓝桥杯编译器版本问题,仅供参考

#include <bits/stdc++.h>
using namespace std;
// https://www.dotcpp.com/oj/problem2571.html
// 用到了C++自带的转换函数,在C语言网的oj能过,但是蓝桥杯的oj跑不了,嘛,当拓展思维了
int ji[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int run[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool judge(string tar) //判断一个日期是否合法
{
    string y = tar.substr(0, 4);
    string m = tar.substr(4, 2);
    string d = tar.substr(6, 2);
    long long year, month, day;
    if (!y.empty())
        year = stoi(y);
    if (!m.empty())
        month = stoi(m);
    if (!d.empty())
        day = stoi(d);
    if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0)
    {
        if (month <= 12 && month >= 1)
        {
            if (day <= run[month] && day >= 1)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
    {
        if (month <= 12 && month >= 1)
        {
            if (day <= ji[month] && day >= 1)
                return true;
            else
                return false;
        }
        else
            return false;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    string now;
    cin >> now;
    int start2 = stoi(now.substr(0, 2));
    int start1 = stoi(now.substr(0, 4));
    for (int i = start1; i <= 9999; i++)
    {

        string front = to_string(i);
        string after = front;
        reverse(after.begin(), after.end());
        string a = front + after;
        if (a <= now)
            continue;
        if (judge(a))
        {
            cout << a << endl;
            break;
        }
    }
    for (int i = start2; i <= 99; i++)
    {
        string front = to_string(i);
        string after = front;
        reverse(after.begin(), after.end());
        string a = front + front;
        a += after;
        a += after;
        if (a <= now)
            continue;
        if (judge(a))
        {
            cout << a;
            break;
        }
    }
    //	cout<<judge(now);
    return 0;
}

成绩分析

按步模拟即可

#include <bits/stdc++.h>
using namespace std;
// https://www.dotcpp.com/oj/problem2591.html
// 注意四舍五入的写法
// ans1 = lower_bound(a + 1, a + 1 + n, 85) - a-1;
// 后面要多减去1,因为数组从1开始存数
int a[10000];
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    sort(a + 1, a + 1 + n);
    int ans1 = lower_bound(a + 1, a + 1 + n, 85) - a-1;
    int ans2 = lower_bound(a + 1, a + n + 1, 60) - a-1;
    double a1=n-ans1;
    double a2=n-ans2;
    a1=a1/n*100;
    a2=a2/n*100;
    a2=int(a2+0.5);
    a1=int(a1+0.5);
    cout<<a2<<"%"<<endl;
    cout<<a1<<"%";
    return 0;
}

平面分析

一道数学题,直接搬公式即可

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值