C++程序设计竞赛(蓝桥杯——模拟与搜索)

这篇文章展示了几个2021年省赛蓝桥杯编程题目,涉及数字游戏(如1的卡片数、回文日期、赢球票等)、数学逻辑(既约分数、数的分解),以及图形问题(九宫幻方)和路径优化(穿越雷区、扫地机器人)。
摘要由CSDN通过智能技术生成

1 卡片(2021省赛蓝桥杯)

在这里插入图片描述

//思路:从1开始枚举,每个数进行枚举后从牌库里减去相应的牌,
//因为从1开始,11,12,13等等,所以1的牌最先没有,所以只判断1,在1的牌数归零后,输出
#include<bits/stdc++.h>
using namespace std;
int a[10];//0-9卡片
int main(){
    //每张卡片有2021张
    for(int i=0;i<=9;i++){
        a[i]=2021;
    }
    for(int j=1; ;j++){
        int c=j;
        while(c){
            int b=c%10;//取出c的最后一位
            if(b==1){
                a[1]--;//如果b为1,就减去一张牌
            }
            if(a[1]==0){
                printf("%d ",j);
                return 1;
                //当1的牌归零后,输出,并且终止程序
            }
            c=c/10;
        }
    }
    return 0;
}

2 回文日期(2020省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int month[13]={-1,31,28,31,30,31,30,31,31,30,31,30,31};
int date,ans1,ans2;
bool check1(int date){
    string s= to_string(date);
    if(s[0]==s[7]&&s[1]==s[6]&&s[2]==s[5]&&s[3]==s[4])
        return true;
    return false;
}
bool check2(int date){
    string s= to_string(date);
    if(s[0]==s[2]&&s[0]==s[5]&&s[0]==s[7]&&s[1]==s[3]&&s[1]==s[4]&&s[1]==s[6])
        return true;
    return false;
}
int main(){
    scanf("%d",&date);
    //枚举日期模板
    int y=date/10000,m=date/100%100,d=date%100;
    for(int i=y; ; i++){
        if(i%400==0||(i%100!=0&&i%4==0))
            month[2]=29;
        else
            month[2]=28;
        int j=(i==y)?m:1;
        for(;j<=12;j++){
            int k=(i==y&&j==m)?d+1:1;
            for(;k<=month[j];k++){
                int data=i*10000+j*100+k;
                if(check1(data)&&ans1==0)
                    ans1=data;
                if(check2(data)) {
                    ans2 = data;
                    return cout<<ans1<<'\n'<<data<<'\n',0;
                }
            }
        }
    }

    return 0;
}

日期枚举模板

	int month[13]={-1,31,28,31,30,31,30,31,31,30,31,30,31};    
	、、、、、、、、
	int y=date/10000,m=date/100%100,d=date%100;
    for(int i=y; ; i++){
        if(i%400==0||(i%100!=0&&i%4==0))
            month[2]=29;
        else
            month[2]=28;
        int j=(i==y)?m:1;
        for(;j<=12;j++){
            int k=(i==y&&j==m)?d+1:1;
            for(;k<=month[j];k++){
                int data=i*10000+j*100+k;
                }

3 赢球票(2016省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10;
int n,a[N],flag[N];
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    int ans = 0;//ans表示答案
    for (int i = 1; i <= n; i++) {
        //将所有卡片的flag初始化为0
        for (int j = 1; j <= n; j++) {
            flag[j] = 0;//1为取走,0没被取走
        }
        int num = 1, pos = i, sum = 0, cnt = 0;//num表示数数的值,pos表示当前位置,sum表示能取走卡片的和,cnt表示拿走卡片数量
        while (1) {
            if (cnt == n || num > n)
                break;
            if (flag[pos] == 1) {
                if (pos == n)
                    pos = 1;
                else
                    pos++;
                continue;
            }
            if (num == a[pos]) {
                sum += a[pos];
                cnt++;
                num = 1;
                flag[pos] = 1;
                if (pos == n) {
                    pos = 1;
                } else
                    pos++;
            } else {
                num++;
                if (pos == n)
                    pos = 1;
                else
                    pos++;
            }
        }
        if (sum > ans)
            ans = sum;
    }
    printf("%d",ans);
    return 0;
}

4 既约分数(2020省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int main(){
    int ans=0;
    for(int i=1;i<=2020;i++){
        for(int j=1;j<=2020;j++){
            if(__gcd(i,j)==1)
                ans++;
        }
    }
    printf("%d",ans);
}

求最大公约数

求a和b的最大公约数

__gcd(a,b)//两个下划线

5 数的分解

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
bool check(int num){
    while(num) {
        int a = num % 10;
        if (a == 2 || a == 4)
            return false;
        num /= 10;
    }
    return true;
}
int main(){
    int ans=0;
    for(int i=1;i<=2019;i++){
        for(int j=1;j<=2019;j++){
            for(int k=1;k<=2019;k++){
                if(i!=j&&i!=k&&j!=k&&i+j+k==2019&&check(i)&&check(j)&&check(k))
                    ans++;
            }
        }
    }
    ans/=6;
    printf("%d",ans);
    return 0;
}

6 九宫幻方(2017省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int a[5][5],n,via[10],cnt,ans[5][5];
pair<int,int>p[10];
bool check(){
    int sum=a[1][1]+a[2][2]+a[3][3];
    if(sum!=a[1][3]+a[2][2]+a[3][1])
        return false;
    for(int i=1;i<=3;i++){
        int tmp1=0,tmp2=0;//tmp1代表行的和,tmp2代表列的和
        for(int j=1;j<=3;j++){
            tmp1+=a[i][j];
            tmp2+=a[j][i];
        }
        if(tmp1!=sum||tmp2!=sum)
            return false;
    }
    return true;
}

void dfs(int t){
    if(t>n){
        if(check()){
            cnt++;
            for(int j=1;j<=3;j++){
                for(int k=1;k<=3;k++){
                    ans[j][k]=a[j][k];
                }
            }
        }
        return;
    }

    int x=p[t].first;
    int y=p[t].second;
    for(int i=1;i<=9;i++){
        if(via[i])
            continue;
        a[x][y]=i;
        via[i]=1;
        dfs(t+1);
        a[x][y]=0;
        via[i]=0;
    }
}

int main(){
    for(int i=1;i<=3;i++){
        for(int j=1;j<=3;j++){
            cin>>a[i][j];
            if(!a[i][j])
                p[++n]= make_pair(i,j);
            via[a[i][j]]=1;
        }
    }
    dfs(1);
    if(cnt==1){
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                cout<<ans[i][j];
            }
            printf("\n");
        }
    }else
        printf("Too Many");
    return 0;
}
/*
 * 0 7 2
 * 0 5 0
 * 0 3 0
 */

0 7 2 0 5 0 0 3 0

7 穿越雷区(2015国赛蓝桥杯)

在这里插入图片描述

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

const int N=105;
const int inf=0x3f3f3f3f;
int a[N][N];//a[i][j]表示点的正负信息,1表示能量值为正,0表示能量值为负,-1表示能量值为A或者B
pair<int,int>st,ed;//st记录起点A的位置,ed记录终点B的位置
int n,ans;
int vis[N][N];//vis记录到达点(x,y)的移动步数

void dfs(int x,int y,int cnt){
    //x,y表示该点的位置,cnt表示到达该点需要的移动步数
    //如果移动步数大于ans,那么步数一定步数最优,剪枝
    if(cnt>ans)
        return;
    if(cnt>vis[x][y])
        return;
    if(x<1||x>n||y<1||y>n)
        return;
    if(x==ed.first&&y==ed.second){
        ans=cnt;
        return;
    }

    vis[x][y]=cnt;
    //记录和更新走到(x,y)的步数
    int tx=x-1,ty=y;
    if(a[tx][ty]!=a[x][y])
        dfs(tx,ty,cnt+1);
    tx=x+1,ty=y;
    if(a[tx][ty]!=a[x][y])
        dfs(tx,ty,cnt+1);
    tx=x,ty=y+1;
    if(a[tx][ty]!=a[x][y])
        dfs(tx,ty,cnt+1);
    tx=x,ty=y-1;
    if(a[tx][ty]!=a[x][y])
        dfs(tx,ty,cnt+1);
}

int main(){
    scanf("%d",&n);
    ans=inf;
    //初始化记录步数
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            vis[i][j]=inf;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            char x;
            cin>>x;
            if(x=='A')
                st.first=i,st.second=j,a[i][j]=-1;
            else if(x=='B')
                ed.first=i,ed.second=j,a[i][j]=-1;
            else if(x=='+')
                a[i][j]=1;
            else
                a[i][j]=0;
        }
    }
    dfs(st.first,st.second,0);
    printf("%d",ans);
    return 0;
}

常用无穷大常量——0x3f3f3f3f

const int inf =0x3f3f3f3f;

n++与++n

n++表示n自增前的值,++n表示n自增后的值‘

加入n=3

a[n++]是a[3]

a[++n]是a[4]

8 小朋友崇拜圈(2017省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,ans;
int a[N],vis[N],number[N];

void dfs(int x,int cnt,int id){
    if(vis[x]&&vis[x]!=id)
        return;
    if(vis[x]){
        ans=max(ans,(cnt-1)-number[x]+1);
        return;
    }
    //x表示当前走到的节点,cnt表示当前边的编号,id表示当前路线的编号
    vis[x]=id;//为节点x打上标记
    number[x]=cnt;//为边添加编号
    dfs(a[x],cnt+1,id);
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int j=1;j<=n;j++){
        dfs(j,1,j);
    }
    printf("%d",ans);
    return 0;
}

9 扫地机器人(2019省赛蓝桥杯)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k,a[N];//a[i]表示第i台机器人的位置
bool check(int mid){
    int pos=0;//pos表示1-pos区域已经被清扫,pos+1到n区域未清扫
    for(int i=1;i<=k;i++){
        int t=mid;
        if(pos<a[i])
            t-=(a[i]-pos-1)*2;
        if(t<0)
            return false;
        pos=a[i]+t/2;
    }
    if(pos<n)
        return false;
    return true;
}
int main(){
    scanf("%d %d",&n,&k);
    for(int i=1;i<=k;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+k);//对机器人的位置进行从小到大的确定
    int l=0,r=2*n,ans=2*n;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))
            ans=mid,r=mid-1;
        else
            l=mid+1;
    }
    printf("%d",ans);
    return 0;
}

10 123(2021国赛蓝桥杯)

在这里插入图片描述

1 拿到20%分数

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],sum[N];
int main(){
    int T=1;
    scanf("%d",&T);
    int up=1,x=1;
    for(int i=1;i<=1000000;i++){
        a[i]=x;
        x++;
        if(x>up){
            up++;
            x=1;
        }
    }
    for(int i=1;i<=1000000;i++){
        sum[i]=sum[i-1]+a[i];
    }
    while(T--){
        int l,r;
        cin>>l>>r;
        cout<<sum[r]-sum[l-1];
    }
    return 0;
}
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值