2021年第十二届蓝桥杯省赛C/C++B组题解总结

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第1张图片
考查计算机基础知识,一字节等于8位,1MB=220B
答案:67108864

256*2^20/4

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第2张图片
一道模拟题,注意题目要求求出能够拼到多少,而不是求不够拼出多少,最后结果要减1
答案:3181

#include 

using namespace std;
int cnt[15];

int main()
{
     
    for(int i=0;i<=9;i++) cnt[i]=2021;
    int i;
    for(i=1;;i++){
     
        int t=i;
        while(t){
     
            if(cnt[t%10]==0){
     
                cout<<i-1;
                return 0;
            }
            cnt[t%10]--;
            t/=10;
        }
    }
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第3张图片
根据直线两点式推导转换成直线一般方程ax+by+c=0(见下图)这样就不用考虑斜率是否存在、避免除法的困扰了,通过除以公约数使a,b,c互质,放入set去重就行了,但是要重载操作符。
2021年第十二届蓝桥杯省赛C/C++B组题解总结_第4张图片

答案:40257

#include
#include
#include
using namespace std;
struct node{
     //点
    int x,y;
}p[1000];
struct line{
     //直线
    int a,b,c;//直线一般方程的系数
    bool operator<(const line &p) const {
     
        if (a == p.a) return b == p.b ? c < p.c : b < p.b;
        return a < p.a;
    }
    bool operator==(const line &p) const {
     
        return a == p.a && b == p.b && c == p.c;
    }
};
int cnt;
set<line> se;
int gcd(int a,int b){
     
    return b==0?a:gcd(b,a%b);
}
int gcdd(int a,int b,int c){
     
    return gcd(gcd(a,b),gcd(b,c));
}
int main()
{
     
    int n=20,m=21;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            p[++cnt]={
     i,j};
    for(int i=1;i<=cnt;i++){
     
        for(int j=i+1;j<=cnt;j++){
     
            int a=p[i].y-p[j].y;//系数
            int b=p[j].x-p[i].x;
            int c=p[i].y * (p[i].x-p[j].x)- p[i].x *(p[i].y-p[j].y);
            int t=gcdd(fabs(a),fabs(b),fabs(c));
            se.insert({
     a/t,b/t,c/t});
        }

    }
    cout<<se.size();
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第5张图片
题目给的数很大,如果直接暴力两重循环会超时。转换思路,把n所有的约数求出来,发现 2021041820210418只有128个约数,然后对这128个约数暴力枚举两重循环,计算出结果。可惜这题比赛的时候思路歪了想错了。
答案:2430

#include
#include
using namespace std;
typedef long long LL;
LL yue[101000],cnt;

int main()
{
     
    LL n=2021041820210418;
    for(LL i=1;i<=n/i;i++){
     
        if(n%i==0){
     
            yue[++cnt]=i;
            if(i*i!=n)
                yue[++cnt]=n/i;
        }
    }
    //sort(yue+1,yue+cnt+1);
    //for(int i=1;i<=cnt;i++)cout<
    //cout<
    int ans=0;
    for(int i=1;i<=cnt;i++){
     
        for(int j=1;j<=cnt;j++){
     
            if(n%(yue[i]*yue[j])==0)
                ans++;
        }
    }
    cout<<ans;
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第6张图片
最短路径模版题,dijkstra跑一遍就行了。比赛的时候太赶时间了做完就直接把答案交上去了最后还忘记检查,太懊悔了,比赛结束发现我交的答案竟然是0x3f3f3f3f,我TM直接心态崩了。大家做完一定要好好检查!!!
答案:10266837

#include
#include
#include
#include
using namespace std;
const int N=2510;
int g[N][N],dist[N],st[N];
int n=2021;
int gcd(int a, int b)
{
     
    return b ? gcd(b, a % b) : a;
}
int lcm(int a,int b){
     
    return a*b/gcd(a,b);
}
int dijkstra(){
     
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;

    for(int i=1;i<=n;i++){
     
        int t=-1;
        for(int j=1;j<=n;j++){
     
            if(!st[j] && (t==-1 || dist[j]<dist[t]))
                t=j;
        }
        st[t]=1;
        for(int j=1;j<=n;j++){
     
                dist[j]=min(dist[j],dist[t]+g[t][j]);
        }
    }
    return dist[n];
}
int main(){
     
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
     
            if(i!=j){
     
                if(fabs(i-j)<=21){
     
                    g[i][j]=lcm(i,j);
                    g[j][i]=lcm(i,j);
                }
                else{
     
                    g[i][j]=0x3f3f3f3f;
                    g[j][i]=0x3f3f3f3f;
                }
            }
        }
    cout<<dijkstra();
    //cout<<0x3f3f3f3f;
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第7张图片

【样例输入 1】
46800999
【样例输出 1】
13:00:00
【样例输入 2】
1618708103123
【样例输出 2】
01:08:23
【评测用例规模与约定】
对于所有评测用例,给定的时间为不超过 1018 的正整数。

这算是一道相对比较简单的题了,也是唯一完整做出来的了,除法取模搞定,注意要用longlong。

#include
#include
using namespace std;
typedef long long LL;

int main()
{
     
    LL n;
    cin>>n;
    n/=1000;
    int h=n/3600%24;
    n=n%3600;
    int m=n/60%60;
    n=n%60;
    int s=n%60;
    printf("%02d:%02d:%02d",h,m,s);
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第8张图片

【样例输入】
3
1 4 6
【样例输出】
10
【样例说明】
能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。
1 = 1;
2 = 6 6 4 (天平一边放 6,另一边放 4);
3 = 4 4 1;
4 = 4;
5 = 6 6 1;
6 = 6;
7 = 1 + 6;
9 = 4 + 6 6 1;
10 = 4 + 6;
11 = 1 + 4 + 6。

【评测用例规模与约定】
对于 50% 的评测用例,1 ≤ N ≤ 15。
对于所有评测用例,1 ≤ N ≤ 100,N 个砝码总重不超过 100000。

嗯?不对劲哦,第二题就不会了,01背包?太菜了想不明白。
2021年第十二届蓝桥杯省赛C/C++B组题解总结_第9张图片

【样例输入】
6
【样例输出】
13
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ N ≤ 10;
对于所有评测用例,1 ≤ N ≤ 1000000000。

这数据开的也太大了吧,109次方,没办法了暴力前十个骗分。
2021年第十二届蓝桥杯省赛C/C++B组题解总结_第10张图片

【样例输入】
3 3
0 3
1 2
0 2
【样例输出】
3 1 2
【样例说明】
原数列为 (1, 2, 3)。 第 1 步后为 (3, 2, 1)。 第 2 步后为 (3, 1, 2)。 第 3 步后为 (3, 1, 2)。与第 2 步操作后相同,因为前两个数已经是降序了。

【评测用例规模与约定】
对于 30% 的评测用例,n, m ≤ 1000;
对于 60% 的评测用例,n, m ≤ 5000;
对于所有评测用例,1 ≤ n, m ≤ 100000,0 ≤ ai ≤ 1,1 ≤ bi ≤ n。

上来直接用sort,时间复杂度O(mnlogn),一半分应该能拿到

#include
#include
using namespace std;
int a[101000];

int main()
{
     
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)a[i]=i;
    while(m--){
     
        int p,q;
        cin>>p>>q;
        if(p==0){
     
           sort(a+1,a+q+1,greater<int>());
        }else{
     
            sort(a+q,a+n+1);
        }
    }
    for(int i=1;i<=n;i++) cout<<a[i]<<" ";
    return 0;
}

2021年第十二届蓝桥杯省赛C/C++B组题解总结_第11张图片

【样例输入】
((()
【样例输出】
5
【评测用例规模与约定】
对于 40% 的评测用例,|s| ≤ 200。
对于所有评测用例,1 ≤ |s| ≤ 5000。

好像也是用dp,不会做

总结

这次比赛感觉比想象的难一点,竟然编程第二题就考到了DP,做过以往的题目不会像今年直接编程第二题就无从下手,DP也只会几个经典的模版题,属实想不到,括号那题好像也是DP,真没法做,而且这一块练的也少新的背景根本想不到,更别说列出转移方程。最可气的还是路径那题,标准最短路径模版题,竟然拿不到分!!还是怪自己太粗心、不检查。总得来说虽然这次蓝桥杯拿不到好成绩,有点小遗憾,但是总归在准备过程中还是学到了不少东西。

你可能感兴趣的:(蓝桥杯)