十五届蓝桥杯国赛模拟(上)

题单详情 - 蓝桥云课 (lanqiao.cn)

填空题:

17114 残缺的数字

手动模拟: 

/*
0000011->4,5,6,8,9----->5
1001011->5,6,8,9------->4
0000001->2,3,4,5,6,8,9->7
0100001->2,3,4,8,9----->5
0101011->8,9----------->2
0110110->0,8----------->2
1111111->8------------->1
0010110->0,6,8--------->3
0101001->2,3,8,9------->4
0010110->0,6,8--------->3
1011100->0,6,8--------->3
0100110->0,8----------->2
1010000->0,3,5,6,7,8,9->7
0010011->4,5,6,8,9----->5
0001111->6,8----------->2
0101101->2,8----------->2
0110101->8------------->1
1101010->0,8,9--------->3
*/
#include<iostream>
using namespace std;
int main(){
    cout<<140*20*12*18*35*12<<endl;
    return 0;
}

设计程序模拟:

输入:
0000011
1001011
0000001
0100001
0101011
0110110
1111111
0010110
0101001
0010110
1011100
0100110
1010000
0010011
0001111
0101101
0110101
1101010
#include<iostream>
using namespace std;
string s[10];
int ans=1;
int main(){
    s[0]="1111110";
    s[1]="0110000";
    s[2]="1101101";
    s[3]="1111001";
    s[4]="0110011";
    s[5]="1011011";
    s[6]="1011111";
    s[7]="1110000";      
    s[8]="1111111";
    s[9]="1111011";
    for(int i=1;i<=18;i++){
        string t;
        cin>>t;
        int cnt=0;
        for(int i=0;i<=9;i++){
            int flag=0;
            for(int j=0;j<=6;j++){
                if(t[j]=='1'&&s[i][j]!='1'){
                    flag=1;
                    break;
                }
            }
            if(flag==0) cnt++;
        }
        ans*=cnt;
    }
    cout<<ans<<endl;
    return 0;
}
输出:
254016000

17142 弹珠堆放

等差数列: 

#include <iostream>
using namespace std;
long long x=20230610;
long long a[100000];
int flag;
int main(){
    a[1]=1,a[2]=4,a[3]=10,a[4]=20;
    for(int i=5;i<=10000;i++){
        a[i]=2*a[i-1]-a[i-2]+i;
        if(a[i]>x) {cout<<i-1<<endl;return 0;}
    }
}

17113 跑步计划

手动模拟,翻开电脑上的日历...开始数...数出来的答案是1333

设计程序模拟:

#include<iostream>
using namespace std;
int week,res1,res2;
int flag[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date){
    int month=date%10000/100;
    int day=date%100;
    if(month>12||!month||!day) return false;
    if(day>flag[month]) return false;
    return true;
}
bool judge(int date){
    int month=date%10000/100;
    int day=date%100;
    int a=month/10,b=month%10;
    int c=day/10,d=day%10;
    if(a==1||b==1||c==1||d==1) return true;
    return false;
}
int main(){
    week=7;
    for(int i=20230101;i<=20231231;i++){
        if(check(i)){
            if(judge(i)||week%7==1) res2++;
            else res1++;
            week++;
        }
    }
    cout<<res1+5*res2<<endl;
    return 0;
}

17122 钉板上的正方形

暴力模拟:

枚举4个点+两个判断(边长的判断,坐标的判断)--->若满足则放进set里

#include<iostream>
#include<set>
using namespace std;
struct point{
    int x,y;
}p[100];
set<int>ans;
int main(){
    int a[10][10]={
        {1,1,0,1,0,1,1,1,1,1},
        {1,1,1,0,0,1,1,1,1,0},
        {1,1,0,0,1,0,1,1,1,1},
        {1,0,1,1,0,1,1,1,1,0},
        {1,0,1,0,1,1,1,1,0,0},
        {1,0,0,1,0,1,0,1,0,1},
        {1,1,1,1,1,1,1,1,1,0},
        {0,1,1,1,1,1,1,1,1,0},
        {0,1,1,0,1,0,1,1,1,1},
        {1,0,1,0,0,1,0,1,0,0},
    };
    int k=0;
    for(int i=0;i<10;i++)
        for(int j=0;j<10;j++)
            if(a[i][j]==1) p[k].x=i,p[k].y=j,k++;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++){
            for(int l=j+1;l<k;l++){
                for(int r=l+1;r<k;r++){
                    int dist1=(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y);
                    int dist2=(p[i].x-p[l].x)*(p[i].x-p[l].x)+(p[i].y-p[l].y)*(p[i].y-p[l].y);
                    int dist3=(p[i].x-p[r].x)*(p[i].x-p[r].x)+(p[i].y-p[r].y)*(p[i].y-p[r].y);
                    int maxx=max(max(dist1,dist2),dist3);
                    int minn=min(min(dist1,dist2),dist3);
                    int midd=dist1+dist2+dist3-maxx-minn;
                    if(maxx==2*minn&&minn==midd){
                        if(maxx==dist1){
                            int xx1=p[i].x+p[j].x;
                            int yy1=p[i].y+p[j].y;
                            int xx2=p[l].x+p[r].x;
                            int yy2=p[l].y+p[r].y;
                            if(xx1==xx2&&yy1==yy2) ans.insert(minn);
                        }
                        if(maxx==dist2){
                            int xx1=p[i].x+p[l].x;
                            int yy1=p[i].y+p[l].y;
                            int xx2=p[j].x+p[r].x;
                            int yy2=p[j].y+p[r].y;
                            if(xx1==xx2&&yy1==yy2) ans.insert(minn);
                        }
                        if(maxx==dist3){
                            int xx1=p[i].x+p[r].x;
                            int yy1=p[i].y+p[r].y;
                            int xx2=p[l].x+p[j].x;
                            int yy2=p[l].y+p[j].y;
                            if(xx1==xx2&&yy1==yy2) ans.insert(minn);
                        }
                    }
                }
            }
        }
    }
    cout<<ans.size()<<endl;
    return 0;
}

编程题:

17110 抓娃娃

纯暴力(超时 未AC 20points):

#include<iostream>
using namespace std;
const int N=1e5+5;
int n,m,l[N],r[N];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>l[i]>>r[i];
    for(int i=1;i<=m;i++){
        double L=0.0,R=0.0;
        int ans=0;
        cin>>L>>R;
        for(int i=1;i<=n;i++){
            double x=(l[i]+r[i])/2.0;
            if(L<=l[i]&&R>=r[i]) {ans++;continue;}
            if(L<=l[i]&&R>=x) {ans++;continue;}
            if(R>=r[i]&&L<=x) {ans++;continue;}
        }
        cout<<ans<<endl;
    }
    return 0;
}

注意题目中这个条件:

max{r[i]-l[i]}<=min{R-L}

结论:
如果l[i],r[i]的中点在L到R范围内
那么这个线段至少一半被包含,即满足条件
lower_bound( )和upper_bound( )
都是利用二分查找的方法在一个排好序的数组中进行查找的库函数
lower_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个>=num的数字,找到返回该数字的地址,
不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个>num的数字,找到返回该数字的地址,
不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

优化AC: 

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n,m,a[N];
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        int l,r;
        cin>>l>>r;
        a[i]=l+r;//每个区间的中点(为了不产生浮点数,相对扩大两倍)
    }
    sort(a,a+n);//给中点排序 
    for(int i=0;i<m;i++){
        int L,R;
        cin>>L>>R;
        L*=2,R*=2;//(为了不产生浮点数,相对扩大两倍)
        //二分查找
        int left=lower_bound(a,a+n,L)-a;
        int right=upper_bound(a,a+n,R)-a;
        //计算答案
        cout<<right-left<<endl;
    }
    return 0;
}

17115 定时任务

暴力模拟AC:

先统计一天中的次数,再按照月,日的顺序枚举计算

#include<iostream>
using namespace std;
int Month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},Day[32];
int flagm[13],flagd[32];
string s1,s2,s3,s4,s5;
int count(string a,int b){
    if(a=="*") return b;
    int flag=0,dis=0;
    for(int i=0;i<a.size();i++){
        if(a[i]==',') {flag=1;break;}
        if(a[i]=='-') {flag=2,dis=i;break;}
    }
    if(flag==0) return 1;
    if(flag==1){
        int cnt=1;
        for(int i=0;i<a.size();i++) if(a[i]==',') cnt++;
        return cnt;
    }
    if(flag==2){
        int l=0,r=0;
        if(dis-1==0) l=a[dis-1]-'0';
        else l=(a[dis-2]-'0')*10+(a[dis-1]-'0');
        for(int i=dis+1;i<a.size();i++){
            r*=10;
            r+=a[i]-'0';
        }
        return r-l+1;
    }
}
void countMonth(string a){
    if(a=="*") {for(int i=1;i<=12;i++) flagm[i]=1; return ;}
    int flag=0,dis=0;
    for(int i=0;i<a.size();i++){
        if(a[i]==',') {flag=1;break;}
        if(a[i]=='-') {flag=2,dis=i;break;}
    }
    if(flag==0){
        int x=0;
        for(int i=0;i<a.size();i++){
            x*=10;
            x+=a[i]-'0';
        }
        flagm[x]=1;
        return ;
    }
    if(flag==1){
        int x=0;
        for(int i=0;i<a.size();i++){
            if(a[i]==',') {flagm[x]=1; x=0; continue;}
            x*=10;
            x+=a[i]-'0';
        }
        flagm[x]=1;
        return ;
    }
    if(flag==2){
        int l=0,r=0;
        if(dis-1==0) l=a[dis-1]-'0';
        else l=(a[dis-2]-'0')*10+(a[dis-1]-'0');
        for(int i=dis+1;i<a.size();i++){
            r*=10;
            r+=a[i]-'0';
        }
        for(int i=l;i<=r;i++) flagm[i]=1;
        return ;
    }
}
void countDay(string a){
    if(a=="*") {for(int i=1;i<=31;i++) flagd[i]=1; return ;}
    int flag=0,dis=0;
    for(int i=0;i<a.size();i++){
        if(a[i]==',') {flag=1;break;}
        if(a[i]=='-') {flag=2,dis=i;break;}
    }
    if(flag==0){
        int x=0;
        for(int i=0;i<a.size();i++){
            x*=10;
            x+=a[i]-'0';
        }
        flagd[x]=1;
        return ;
    }
    if(flag==1){
        int x=0;
        for(int i=0;i<a.size();i++){
            if(a[i]==',') {flagd[x]=1; x=0; continue;}
            x*=10;
            x+=a[i]-'0';
        }
        flagd[x]=1;
        return ;
    }
    if(flag==2){
        int l=0,r=0;
        if(dis-1==0) l=a[dis-1]-'0';
        else l=(a[dis-2]-'0')*10+(a[dis-1]-'0');
        for(int i=dis+1;i<a.size();i++){
            r*=10;
            r+=a[i]-'0';
        }
        for(int i=l;i<=r;i++) flagd[i]=1;
        return ;
    }
}
int main(){
    cin>>s1>>s2>>s3>>s4>>s5;
    for(int i=0;i<32;i++) Day[i]=i;
    int cnt1=count(s1,60);
    int cnt2=count(s2,60);
    int cnt3=count(s3,24);
    int cntday=cnt1*cnt2*cnt3;
    int cnt4=0;
    countDay(s4);
    countMonth(s5);
    for(int i=1;i<=12;i++){
        if(flagm[i]==1){
            for(int j=1;j<=Month[i];j++){
                if(flagd[j]==1){
                    cnt4++;
                }
            }
        }
    }
    cout<<cntday*cnt4<<endl;
    return 0;
}

17135 不完整的算式

模拟AC:

#include<iostream>
using namespace std;
string s;
int main(){
    cin>>s;
    int n=s.size();
    if(s[n-1]=='?'){
        long long a=0,b=0;int flag=0;
        for(int i=0;i<n-2;i++) if(!(s[i]-'0'>=0&&s[i]-'0'<=9)) {flag=i;break;}
        for(int i=0;i<flag;i++){a*=10;a+=s[i]-'0';}
        for(int i=flag+1;i<n-2;i++){b*=10;b+=s[i]-'0';}
        if(s[flag]=='+'){cout<<a+b<<endl;return 0;}
        if(s[flag]=='-'){cout<<a-b<<endl;return 0;}
        if(s[flag]=='*'){cout<<a*b<<endl;return 0;}
        if(s[flag]=='/'){cout<<a/b<<endl;return 0;}
    }
    if(s[0]=='?'){
        long long a=0,b=0;int flag=0;
        for(int i=2;i<n;i++) if(s[i]=='=') {flag=i;break;}
        for(int i=2;i<flag;i++){a*=10;a+=s[i]-'0';}
        for(int i=flag+1;i<n;i++){b*=10;b+=s[i]-'0';}
        if(s[1]=='+'){cout<<b-a<<endl;return 0;}
        if(s[1]=='-'){cout<<a+b<<endl;return 0;}
        if(s[1]=='*'){cout<<b/a<<endl;return 0;}
        if(s[1]=='/'){cout<<a*b<<endl;return 0;}
    }
    int key=0;
    for(int i=0;i<n;i++) if(s[i]=='=') {key=i;break;}
    if(s[key-1]=='?'){
        long long a=0,b=0;
        for(int i=0;i<key-2;i++){a*=10;a+=s[i]-'0';}
        for(int i=key+1;i<n;i++){b*=10;b+=s[i]-'0';}
        if(s[key-2]=='+'){cout<<b-a<<endl;return 0;}
        if(s[key-2]=='-'){cout<<a-b<<endl;return 0;}
        if(s[key-2]=='*'){cout<<b/a<<endl;return 0;}
        if(s[key-2]=='/'){cout<<a/b<<endl;return 0;}
    }
    else{
        int l=0,r=0;
        for(int i=0;i<n;i++){
            if(s[i]=='?'){l=i;}
            if(s[i]=='='){r=i;break;}
        }
        long long a=0,b=0,c=0;
        for(int i=0;i<l;i++){a*=10;a+=s[i]-'0';}
        for(int i=l+1;i<r;i++){b*=10;b+=s[i]-'0';}
        for(int i=r+1;i<n;i++){c*=10;c+=s[i]-'0';}
        if(a+b==c) {cout<<"+"<<endl;return 0;}
        if(a-b==c) {cout<<"-"<<endl;return 0;}
        if(a*b==c) {cout<<"*"<<endl;return 0;}
        if(a/b==c) {cout<<"/"<<endl;return 0;}
    }
}

17100 01游戏

这题是N-皇后问题的升级版,下面(我的代码)毫无剪枝痕迹(必超时),考试的时候能拿55points足以:

#include<iostream>
using namespace std;
const int N=50;
int n,maxx,row[N],col[N];
char a[15][15];
void show(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<a[i][j];
        }
        cout<<endl;
    }
}
bool check_num(){
    for(int i=1;i<=n;i++) if(row[i]!=n/2||col[i]!=n/2) return false;
    return true;
}
int check_row(int x,int y){
    for(int i=1;i<=n;i++) if(a[x][i]!=a[y][i]) return 0;
    return 1;
}
int check_col(int x,int y){
    for(int i=1;i<=n;i++) if(a[i][x]!=a[i][y]) return 0;
    return 1;
}
bool check_only(){
    for(int i=1;i<=n-1;i++){
        for (int j=i+1;j<=n;j++){
            int x=check_col(i,j)+check_row(i,j);
            if(x!=0) return false;
        }
    }
    return true;
}
int check_same_row(int x){
    for(int i=1;i<=n-2;i++) if(a[x][i]==a[x][i+1]&&a[x][i+2]==a[x][i+1]) return 1;
    return 0;
}
int check_same_col(int x){
    for(int i=1;i<=n-2;i++) if(a[i][x]==a[i+1][x]&&a[i+2][x]==a[i+1][x]) return 1;
    return 0;
}
bool check_same(){
    for(int i=1;i<=n;i++){
        int x=check_same_row(i)+check_same_col(i);
        if (x!=0) return false;
    }
    return true;
}
void dfs(int x,int y,int cnt){
    if(y==n+1) x++,y=1;
    if(x==n+1){
        if(cnt==maxx&&check_num()&&check_only()&&check_same()){
            show();
        }
        return;
    }
    if(a[x][y]!='_') dfs(x,y+1,cnt);
    if(a[x][y]=='_'){
        a[x][y]='0';
        dfs(x,y+1,cnt);
        a[x][y]='_';
    }
    if(a[x][y]=='_'){
        a[x][y]='1';
        row[x]++,col[y]++;
        dfs(x,y+1,cnt+1);
        row[x]--,col[y]--;
        a[x][y]='_';
    }
    return;
}
int main() {
    cin>>n;
    int temp=0;
    maxx=n*n/2;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
            if(a[i][j]=='1'){
                row[i]++;
                col[j]++;
                temp++;
            }
        }
    }
    maxx-=temp;
    dfs(1,1,0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值