蓝桥杯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; }
stay hungry stay foolish

浙公网安备 33010602011771号