蓝桥杯2020.10.17B组c++

 

1.门牌制作

 暴力即可

#include <iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define N 100000
#define INF 0xffffff
using namespace std;
typedef long long LL;
int main() {
    int i,j,count,len;
    char s[4];
    count=0;
    for(i=1;i<=2020;i++){
        len=sprintf(s,"%d",i);
        for(j=0;j<len;j++)if(s[j]=='2')count++;
    }
    cout<<count;
    return 0;
}
//624

 

2.约分分数

#include <iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define N 100000
#define INF 0xffffff
using namespace std;
typedef long long LL;
int main() {
    int i,j,count=0;
    for(i=1;i<=2020;i++){
        for(j=1;j<=2020;j++){
            if(__gcd(i,j)==1)count++;
        }
    }
    cout<<count;
    return 0;
}
//2481215

 

3.蛇形矩阵

找规律即可

俗话说的:从哪里跌倒从哪里爬起来!

1

2   3

4   5   6

7   8   9   10

11 12 13 14 15

16 17 18 19 20 21

22 23 24 25 26 27 28

29 30 31 32 33 34 35 36

37 38 39 40 41 42 43 44 45

求20行中最左边的数和最右边的数,求中位数就是结果

#include <iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define N 100000
#define INF 0xffffff
using namespace std;
typedef long long LL;
int main() {
    int sum1,sum2;
    int i;
    for(i=1;i<=38;i++)sum1+=i;
    for(i=1;i<=39;i++)sum2+=i;
    sum1++;
    cout<<(sum1+sum2)/2; 
    return 0;
}
//761

 

4.跑步训练 

#include <iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define N 100000
#define INF 0xffffff
using namespace std;
typedef long long LL;
int main() {
    int i,j,k,week=5;
    int sum=0,m=12;
    int a[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
    for(i=2000;i<=2020;i++){
        if(i%400==0||(i%4==0&&i%100!=0))a[2]=29;
        else a[2]=28;
        if(i==2020)m=10;
        for(j=1;j<=m;j++){
            if(i==2020&&j==10)a[j]=1;
            for(k=1;k<=a[j];k++){
                if(k==1||week==0)sum+=2;
                else sum+=1;
                week=(week+1)%7;
            }
        }
    }
    cout<<sum;
    return 0;
}
//8879

 

5.七段码

大致的想法如下(并查集),仔细审题说的是必须有亮边

构建二极管图

位运算遍历每一种组合,将每条亮的边的临亮边合并

最后判断亮的边是否根一样

#include<iostream>
#include<algorithm> 
#include<string.h>
using namespace std;
int tree[7];
int find(int x){
    if(x==tree[x])return x;
    return tree[x]=find(tree[x]);
}
void combine(int x,int y){
    x=find(x);
    y=find(y);
    if(x!=y)tree[y]=x;
}
int main() {
    int g[7][7]={
        //   a b c d e f g
            {0,1,0,0,0,1,0},
            {1,0,1,0,0,0,1},
            {0,1,0,1,0,0,1},
            {0,0,1,0,1,0,0},
            {0,0,0,1,0,1,1},
            {1,0,0,0,1,0,1},
            {0,1,1,0,1,1,0}
    };
    int i,j,k,s[7]; 
    int num,count=0,root,flag;
    
    for(i=1;i<=127;i++){
        num=i,j=6;
        memset(s,0,sizeof(s));
        while(num){
            s[j--]=num&1;
            num=num>>1;    
        }
        for(j=0;j<7;j++)tree[j]=j;
        for(j=0;j<7;j++)if(s[j])for(k=0;k<7;k++)if(g[j][k]&&s[k])combine(j,k);
        
        flag=0;
        for(j=0;j<7;j++){
            if(s[j]){
                if(!flag){
                    root=find(j);
                    flag=1; 
                }else if(root!=find(j))break;
            }
        }
        if(j==7)count++;    
    }
    cout<<count;
    return 0;
}

 

6.成绩统计

#include <iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define N 100000
#define INF 0xffffff
using namespace std;
typedef long long LL;
int main() {
    int n;
    int i,a,b,t;
    int ans1,ans2;
    cin>>n;
    a=b=0;
    for(i=0;i<n;i++){
        cin>>t;
        if(t>=60)a++;
        if(t>=85)b++;
    }
    ans1=round((double)a/n*100);
    ans2=round((double)b/n*100);    
    cout<<ans1<<"%"<<endl;
    cout<<ans2<<"%"<<endl;
    return 0;
}

 

7.回文日期

模拟即可;is为判断是否回文,judge为判断是不是ABABBABA型,注意A!=B

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int is(char a[],int s,int e){
    if(s>=e)return 1;
    if(a[s]==a[e])return is(a,s+1,e-1);
    return 0;
} 
int judge(char a[]){
    char A,B;
    A=a[0],B=a[1];
    if(A!=B&&a[0]==A&&a[1]==B&&a[2]==A&&a[3]==B&&a[4]==B&&a[5]==A&&a[6]==B&&a[7]==A)return 1;
    return 0;
}
int main(){
    char a[8],ans1[8],ans2[8];
    int y,m,d,month[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
    int flag1=0,flag2=0,len;
    
    cin>>a;
    y=(a[0]-'0')*1000+(a[1]-'0')*100+(a[2]-'0')*10+a[3]-'0',m=(a[4]-'0')*10+(a[5]-'0'),d=(a[6]-'0')*10+(a[7]-'0');
    while(!flag1||!flag2){
        if(y%400==0||(y%4==0&&y%100!=0))month[2]=29;
        else month[2]=28;
        d++;
        if(d>month[m]){m++;d=1;}
        if(m>12){y++;m=1;};
        
        len=sprintf(a,"%04d%02d%02d",y,m,d);
        if(!flag1&&is(a,0,len-1)){strcpy(ans1,a);flag1=1;}
        if(!flag2&&judge(a)){strcpy(ans2,a);flag2=1;} 
    }
    cout<<ans1<<endl;
    cout<<ans2<<endl;
    return 0;
} 

 

8.子串分值和

分析题,考试的时候纯暴力出来的只能完成10^3内的数,之后看网友们的解题,瞬间怀疑自己

主要思想,每个字符只有第一次出现的时候才会作为一个不同的字母,所以我们找出每个字符第一次出现的所以组合,然后累加;

演示过程
ababc
01234 a:[00] [01] [02] [03] [04] //1*5就是5种[ij]就是下标i到j b:[01] [02] [03] [04] [11] [12] [13] [14] //2*4 就是8种 a:[12] [13] [14] [22] [23] [24] //2*3 就是6种 b:[23] [24] [33] [34] //2*2就是4种 c:[04] [14] [24] [34] [44] //5*1就是5种 5+8+6+4+5=28

变量含义:

i是目前遍历到的下标(以0开始)

last[c-'a']是字母c上次出现的下标,

所以能得到本次的组合是[last[a[i]-'a']+1,i]*[i,strlen(a)-1]
所以得出公式count+=(i-(last[a[i]-'a']+1)+1)*(strlen-i);

发现知道这个东西很简单,但是推理过程哇太神奇,感觉十个脑子我都想不出来了,哎这个让我怀疑自我智商

#include<stdio.h>
#include<iostream>
#include<string.h>
#define N 100005
using namespace std;
int main(){
    int last[26],i;
    long long count=0;
    char a[N];
    scanf("%s",a);
    for(i=0;i<26;i++)last[i]=-1;
    for(i=0;i<strlen(a);i++){
        count+=(i-(last[a[i]-'a']+1)+1)*(strlen(a)-i);
        last[a[i]-'a']=i;
    }
    printf("%lld",count);
    return 0; 
} 

 

posted @ 2020-10-28 16:46  金龙喩  阅读(221)  评论(0)    收藏  举报