蓝桥杯2022B题解

九进制转十进制

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
//#define int long long
using namespace std;

void solve(){
    int n=2022;
    int ans=0;
    int t=1;
    while(n){
        ans+=(n%10)*t;;
        n/=10;
        t*=9;
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

每位的数字乘9^(位数),再相加即可

顺子日期

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
//#define int long long
using namespace std;

void solve(){
    cout<<14<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

20221230,20221231,20221123,20221012,2022012(0到9),总共14个

刷题统计

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;

void solve(){
    int a,b,n;
    cin>>a>>b>>n;
    int temp=a*5+b*2;
    int ans=(n/temp)*7;
    n%=temp;
    if(n>0) loop(i,1,5){
        ans++;
        n-=a;
        if(n<=0) break;
    }
    if(n>0) loop(i,1,2){
        ans++;
        n-=b;
        if(n<=0) break;
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

先算出前面完整的一周完成的作业数记录到ans里,然后特判最后不完整的一周,加到ans里,输出ans

修剪灌木

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;

void solve(){
    int n;cin>>n;
    loop(i,1,n/2){
        cout<<(n-i)*2<<'\n';
    }
    loop(i,(n/2)+1,n){
        cout<<(i-1)*2<<'\n';
    }
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

每棵树最高长到max(这个树到左边的距离,这个数到右边的距离)*2

X进制减法

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;

inline int Mod(int x){
    while(x<0) x+=mod;
    return x%mod;
}

void solve(){
    int n;cin>>n;
    int pw=1;
    int na,nb;
    cin>>na;
    ve<int> a(na+1);
    loop(i,1,na) cin>>a[i];
    cin>>nb;
    ve<int> b(nb+1);
    loop(i,1,nb) cin>>b[i];
    int ans=0;
    loop(i,1,max(na,nb)){
        if(i<=na&&i<=nb){
            int temp=max(2ll,max(a[na-i+1],b[nb-i+1])+1);
            ans=Mod(ans+(a[na-i+1]-b[nb-i+1])*pw);
            pw=Mod(pw*temp);
            continue;
        }
        if(i<=na){
            ans=Mod(ans+(a[na-i+1])*pw);
            pw=Mod(pw*max(a[na-i+1]+1,2ll));
        }
        if(i<=nb){
            ans=Mod(ans+(b[nb-i+1])*pw);
            pw=Mod(pw*max(b[nb-i+1]+1,2ll));
        }
    }
    cout<<ans<<'\n';
}

signed main(){
    //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

每位的进制数取到能取的最小值,最后结果就最小,因为假设从高位到低位,第一个不同的数(a[i1]-b[i1])必然大于0,第二个不同的数(a[i2]-b[i2])就算小于0,加上(a[i1]-b[i1])也会大于0,依此类推,那么让每个进制取最小,求和就最小

统计子矩阵

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;

int a[510][510];
int s(int e,int b,int c,int d){
    return a[c][d]-a[e-1][d]-a[c][b-1]+a[e-1][b-1];
}

void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    loop(i,1,n){
        loop(j,1,m){
            cin>>a[i][j];
            a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        }
    }
    int ans=0;
    loop(i,1,n){
        loop(j,i,n){
            int tt=0;
            loop(t,1,m){
                while(tt<t||(s(i,t,j,tt)<=k&&tt<=m)) tt++;
                ans+=tt-t;
            }
        }
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

用二维前缀和存矩阵a,然后枚举i,j,t,tt为矩阵的四个顶点,但是O(n4)超时,所以后两个指针用双指针优化O(n3)能过

积木画

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;

void solve(){
    int n;cin>>n;
    ve<int> dp(4);
    dp[0]=1;
    dp[1]=1;
    loop(i,2,n){
        ve<int> g(4);
        g[0]=dp[1];
        g[1]=(dp[1]+dp[2]+dp[3]+dp[0])%mod;
        g[2]=(dp[0]+dp[3])%mod;
        g[3]=(dp[0]+dp[2])%mod;
        swap(dp,g);
    }
    cout<<dp[1]<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

考虑dp,g为dp的下一层,dp[0]为最末尾一列没有积木,dp[1]为最后一列满积木,dp[2],为最后一列上面有积木,dp[3]为最后一列下面有积木,可以推出上面的dp转移

扫雷

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define N 500004
#define NN 50004
using namespace std;
int head[N],nxt[N],edge[N],ind;
bool check[NN];
int num[NN],rr[NN];
int ans;
unordered_map<int,int> mp;

void add(int a,int b){
    nxt[++ind]=head[a];
    head[a]=ind;
    edge[ind]=b;
}

int query(int x,int y){
    int key=x*1000000001+y;
    if(mp.count(key)) return mp[key];
    else return 0;
//    int t=((key%N)+N)%N;
//    for(int i=head[t];i;i=nxt[i]){
//        if(edge[i]==key) return i;
//    }
//    return 0;
}

void insert(int x,int y){
    int key=x*1000000001+y;
    mp[key]=++ind;
    edge[ind]=key;
    //int t=((key%N)+N)%N;
    //add(t,key);
}

void dfs(int x){
    ans+=num[x];
    check[x]=1;
    int dx=edge[x]/1000000001;
    int dy=edge[x]%1000000001;
    loop(i,-rr[x],rr[x]){
        loop(j,-rr[x],rr[x]){
            int temp=query(dx+i,dy+j);
            if(i*i+j*j<=rr[x]*rr[x]&&temp&&check[temp]==0){
                dfs(temp);
            }
        }
    }
}

void solve(){
    int n,m;
    cin>>n>>m;
    loop(i,1,n){
        int x,y,r;
        cin>>x>>y>>r;
        if(query(x,y)==0) insert(x,y);
        rr[query(x,y)]=max(rr[query(x,y)],r);
        num[query(x,y)]++;
    }
    loop(i,1,m){
        int x,y,r;
        cin>>x>>y>>r;
        loop(j,-r,r){
            loop(k,-r,r){
                int temp=query(x+j,y+k);
                if(j*j+k*k<=r*r&&temp&&check[temp]==0){
                    dfs(temp);
                }
            }
        }
    }
    cout<<ans<<'\n';
}

signed main(){
    //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

用map把坐标映射成数字(1,2,3…),然后枚举每一颗雷的射程范围,用dfs把雷清空

李白打酒加强版

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;

int dp[110][110][110];
void solve(){
    memset(dp,0,sizeof(dp));
    int n,m;
    cin>>n>>m;
    dp[0][0][2]=1;
    loop(i,0,n){
        loop(j,0,m){
            loop(k,0,110){
                if(i&&(k%2==0)) dp[i][j][k]+=dp[i-1][j][k/2];
                dp[i][j][k]%=mod;
                if(j) dp[i][j][k]+=dp[i][j-1][k+1];
                dp[i][j][k]%=mod;
            }
        }
    }
    cout<<dp[n][m-1][1]<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;cin>>t;
    while(t--) solve();
    return 0;
}

考虑dp,dp[店的数量][花的数量][剩余的酒],有转移dp[i][j][k]+=dp[i-1][j][k/2],dp[i][j][k]+=dp[i][j-1][k+1]

最后输出dp[n][m-1][1]

砍竹子

#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
const int N = 2e5 + 10;
using namespace std;

int a[N][20];

int f(int x){
    return sqrt(x/2+1);
}

void solve(){
    int n;cin>>n;
    int ans=0;
    loop(i,1,n){
        int temp;cin>>temp;
        int t[20],top=0;
        while(temp>1){
            t[top++]=temp;
            temp=f(temp);
        }
        ans+=top;
        int top2=0;
        while(top){
            a[i][top2++]=t[--top];
        }
    }
    loop(i,1,n){
        loop(j,0,15){
            if(a[i][j]!=0&&a[i][j]==a[i+1][j]) ans--;
        }
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t=1;//cin>>t;
    while(t--) solve();
    return 0;
}

用a[N][20]存下每颗树每次被砍的高度,显然被砍不多次就会变1,所以20够存,如果a[i][j]==a[i][j+1],就可以少砍一次

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值