蓝桥杯2020B组省赛题解

门牌制作

遍历求解

#include<iostream>
 
using namespace std;
 
int main(){
    int cnt=0;
    for(int i=1;i<=2020;i++){
        int t=i;
        while(t){
            if(t%10==2) cnt++;
            t/=10;
        }
    }
    cout<<cnt;
    return 0;
}

即约分数

最大公约数+遍历

#include<iostream>
 
using namespace std;
 
int gcd(int a,int b){
    return b ? gcd(b,a%b) : a;
}
 
int main(){
    int cnt=0;
 
    for(int i=1;i<=2020;i++){
        for(int j=1;j<=2020;j++){
            int t=gcd(i,j);
            if(t==1) cnt++;
        }
    }
 
    cout<<cnt;
    return 0;
}

蛇形填数

看规律

第(2n-1)行存在(a,a)

用等差数列求和+20就可以算出结果

#include<iostream>
#include<cstdlib>
 
using namespace std;
 
int main(){
    int n=(1+38)*38/2+20;
    cout<<n;
    return 0;
}

七段码

我是建图+dfs写的,用map标记是否记录过

#include<iostream>
#include<cstring>
#include<map>
#include<cmath>
 
using namespace std;
 
const int N=100;
 
int h[N],e[N],ne[N],idx;
map<int,int> v;
bool st[10];
int cnt;
 
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void x(int a,int b){
    add(a,b),add(b,a);
}
 
void dfs(int a,int x){
    if(v[x]==0) cnt++,v[x]=1;
 
    for(int i=h[a];i!=-1;i=ne[i]){
        int j=e[i];
        if(!st[j]){
            st[j]=true;
            dfs(j,x+j*(int)pow(10,j));
            st[j]=false;
        }
    }
}
 
int main(){
    memset(h,-1,sizeof(h));
    int n=7+10+16;
 
    x(1,2),x(2,3),x(3,4),x(4,5),x(5,6),x(1,6),x(7,2),x(7,3),x(7,5),x(7,6);
 
    for(int i=1;i<=7;i++){
        st[i]=true;
        dfs(i,i*(int)pow(10,i));
        st[i]=false;
    }
     
    cout<<cnt;
    return 0;
}

跑步锻炼

模拟

表示出月初和周一,遍历

#include<iostream>
 
using namespace std;
 
int d,w,m,y;
int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int res;
 
inline void update(){
    if(w>7) w=1;
 
    if(y==4 && m==2){
        if(d>mon[2]+1){
            d=1,m++;
        }
    }
    else if(d>mon[m]) d=1,m++;
 
    if(m>12) m=1,y++;
 
    if(y>4) y=1;
}
 
int main(){
    int n=(365*20+5)+(366-92+1);
    d=1,w=6,m=1,y=4;
 
    while(n--){
        update();
 
        if(w==1 || (d==1 && w!=1)) res++;
 
        res++;
        d++,w++;
    }
 
    cout<<res;
    return 0;
}

回文日期

思路就是,遍历年份,根据年份确定回文月份(并找出符合格式的),找到后标记、输出

(我写的可能复杂了,有些步骤可以省掉或换掉的)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
 
using namespace std;
 
int t;
int n;
int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 
bool check(int yy, int mm, int dd) {
    if(mm >= 1 && mm <= 12) {
        if((yy % 400 == 0) || (yy % 4 == 0 && yy % 100 != 0)) {
            m[2] = 29;
        }
        if(m[mm] >= dd && dd != 0)
            return true;
        else
            return false;
    }
    return false;
}
 
int main(){
    cin>>t;
 
    while(t--){
        scanf("%d",&n);
        int d=n;
        n/=10000;
 
        bool f1=false,f2=false;
        int r1,r2;
 
        for(int i=n;i<=9999;i++){
            string t1=to_string(i),t2=t1;
            reverse(t2.begin(),t2.end());
             
            int a=stoi(t2)/100,b=stoi(t2)%100;
 
            if(!check(i,a,b)) {m[2]=28;continue;}
 
            int dt=stoi(t1+t2);
            if(!f1 && dt>d){
                r1=dt;
                f1=true;
            }
            if(!f2 && dt>d && a==b){
                r2=dt;
                f2=true;
            }
            if(f1 && f2) break;
        }
        printf("%d\n%d\n",r1,r2);
    }
    return 0;
}

字串排序

不会

成绩统计

判断+存不同组别的人数,分别计算

#include<iostream>
#include<cstdio>
#include<cmath>
 
using namespace std;
 
int s[3];
 
int main(){
    int n;
    scanf("%d",&n);
 
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
         
        if(x>=85){
            s[2]++;
        }else if(x>=60){
            s[1]++;
        }else{
            s[0]++;
        }
    }
 
    int a=round(100.0*s[2]/n);
    int b=round(100.0*(s[2]+s[1])/n);
 
    printf("%d\%\n%d\%\n",b,a);
    return 0;
}

子串分值和

ac 60%

理解起来比较简单,就是模拟了一下,分成不同长度的子串分别来计算

#include<iostream>
#include<cstring>
#include<queue>
 
using namespace std;
 
int sum;
 
int main(){
    string s;
    cin>>s;
 
    for(int k=1;k<=s.size();k++){
        queue<int> q;
        int cnt=0;
        int n[26]={0};
        for(int i=0;i<s.size();i++){
            int t=s[i]-'a';
 
            q.push(t);
             
            if(q.size()>k){
                int tt=q.front();
                q.pop();
                 
                n[tt]--;
                if(n[tt]==0) cnt--;
            }
 
            if(n[t]==0) cnt++;
            n[t]++;
 
            if(q.size()==k) sum+=cnt;
        }
    }
 
    cout<<sum;
    return 0;

ac 100%

这个解法不知道用了什么数学知识,反正我不会

#include<iostream>
#include<cstring>

using namespace std;

typedef long long LL;

int num[26];

int main(){
    string s;
    cin>>s;

    int len=s.size();
    memset(num,-1,sizeof(num));
    LL res=0;

    for (int i=0;i<len;++i){
        res+=(LL)(i-num[s[i]-'a'])*(len-i);
        num[s[i]-'a']=i;
    }

    printf("%lld\n",res);
    return 0;
}

平面切分

平面上多一条直线+1,并且这条直线有一个交点额外+1

map存已经计算在内的点(判断每条直线之前要clear一下)

注意相同的直线和斜率不存在的直线

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
 
using namespace std;
 
typedef pair<double,double> PDD;
typedef pair<int,int> PII;
const int N=1e3+10;
 
PII v[N];
int n,res=1,cnt;
map<PDD,int> m;
bool flag;
 
int main(){
    scanf("%d",&n);
 
    int x,y;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        v[i]={x,y};
 
        cnt=1;
        m.clear();
        flag=false;
        for(int j=1;j<i;j++){
            if(i==1) break;
 
            if(x==v[j].first && y==v[j].second){
                flag=true;
                break;
            }
 
            if(x==v[j].first) continue;
            double xx=((double)y-v[j].second)/(v[j].first-x);
            double yy=xx*x-y;
 
            if(m[{xx,yy}]==0){
                cnt++;
                m[{xx,yy}]=1;
            }
        }
        if(!flag) res+=cnt;
    }
 
    printf("%d",res);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯是一个国内著名的计算机比赛,为了帮助参赛者更好地准备和了解比赛的题型,委会会公布历年的真题并提供相应的题解。 首先,我们需要了解蓝桥杯是一个综合性的计算机比赛,测试的对象包括计算机基础知识、编程能力以及解决实际问题的能力。 在历年的真题中,参赛者将面临不同类型的题目,包括算法设计与优化问题、数据结构与算法问题、编程题等。其中针对Python B的题目主要考察的是对Python语言的掌握和应用能力。 题目解答一般会包含以下几个方面的内容: 1. 题目分析与理解:读取题目,理解题目的要求和限制条件。通过仔细分析题目,确定题目的输入与输出,以及问题的核心。 2. 设计解决方案:根据题目要求和限制条件,设计一个合适的解决方案。可以使用合适的算法和数据结构来解决问题,并做出相应的性能优化。 3. 编写代码实现:根据设计的方案编写相应的代码实现。需要注意的是,Python语言有其独特的语法和特性,掌握好这些特性可以更好地完成编程任务。 4. 调试与测试:编写完代码后,需要进行调试和测试。通过运行样例输入和输出,检查代码是否符合题目要求,并且没有逻辑上的错误。 5. 总结与优化:在完成题目解答后,可以进行总结和优化。包括分析算法复杂度、代码风格和可读性等方面,以便在比赛中更好地表现。 在准备蓝桥杯时,可以通过阅读历年的真题和题解来了解比赛的难度和类型,针对性地进行练习和提高。同时也可以参加相关的培训班和讨论活动,与其他参赛者交流经验和技巧。 总而言之,历年蓝桥杯真题的解答对于提高自己的编程能力和应对比赛非常有帮助。通过认真分析和实践,可以更好地理解并掌握Python编程,并在比赛中取得更好的成绩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值