蓝桥杯第十一届C/C++ B组省赛真题整理

蓝桥杯第十一届C/C++ B组省赛真题整理

试题A: 门牌制作 解法:模拟

【问题描述】
    小蓝要为一条街的住户制作门牌号。	
    这条街一共有2020位住户,门牌号从1到2020编号。
    小蓝制作门牌的方法是先制作О到9这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017需要依次粘贴字符1、0、1、7,即需要1个字符0,2个字符1,1个字符7。
    请问要制作所有的1到2020号门牌,总共需要多少个字符2?
【答案提交】
	这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include<iostream>
using namespace std;
int ans;
void count(int x){
    while(x){
        if(x%10==2) ans++;
        x/=10;
    }
}
int main()
{
    for(int i=1;i<=2020;i++) count(i);
    cout<<ans<<endl;
    return 0;
}

答案:624

试题B: 既约分数 解法:枚举+gcd

【问题描述】
    如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。
    例如,3/4,5/2,1/8,7/1都是既约分数。
    请问,有多少个既约分数,分子和分母都是1到2020之间的整数(包括1和2020)?
【答案提交】
    这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include<iostream>
using namespace std;
int ans;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main()
{
    for(int i=1;i<=2020;i++)
        for(int j=1;j<=2020;j++) 
            if(gcd(i,j)==1) ans++;
    cout<<ans<<endl;
    return 0;
}

答案:2481215

试题C: 蛇形填数 解法:模拟

【问题描述】
    如下图所示,小明用从1开始的正整数“蛇形”填充无限大的矩阵。
                1   2   6   7   15  ...
                3   5   8   14  ...
                4   9   13  ...
                10  12  ...
                11  ...
                ...
    容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20行第20列的数是多少?
【答案提交】
	这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include<iostream>
using namespace std;
int a[50][50],cnt;
int main()
{
	for(int n=2;n<=40;n++)
		for(int i=1;i<n;i++){
			if(n%2) a[i][n-i]=++cnt;
			else a[n-i][i]=++cnt;
		}
	cout<<a[20][20]<<endl;
	return 0;
} 

答案:761

试题D: 跑步锻炼 解法:日期计算

【问题描述】
    小蓝每天都锻炼身体。
    正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。
    小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?
【答案提交】
	这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include<iostream>
using namespace std;
int d[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main()
{
	int year=2000,month=1,day=1,week=5,ans=0;
	while(1){
		if(day==1||week==0) ans+=2;
		else ans++;
		week=(week+1)%7;
		if(year==2020&&month==10&&day==1) break;
		if(++day>d[month]){
			day=1;
			if(++month>12){
				month=1;
				year++;
				if(year%4==0&&year%100||year%400==0) d[2]=29;
				else d[2]=28;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
} 

答案:8879

试题E: 七段码 解法:搜索

【问题描述】
    小蓝要用七段码数码管来表示一种特殊的文字。
    上图给出了七段码数码管的一个图示,数码管中一共有7段可以发光的二极管,分别标记为a, b, c, d, e, f, g。
    小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
    例如:b发光,其他二极管不发光可以用来表达一种字符。
    例如: c发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
    例如: a, b, c, d,e发光,f,g不发光可以用来表达一种字符。
    例如: b, f发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
    请问,小蓝可以用七段码数码管表达多少种不同的字符?
【答案提交】
	这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include<iostream>
#include<queue>
using namespace std;
int g[7][7];
bool check(int x){
	queue<int> que;
	bool vis[7]={0};
	int S;
	for(int i=0;i<7;i++)	
		if(x>>i&1){
			vis[i]=true;
			S=i;
		}
	que.push(S);
	vis[S]=;
	while(!que.empty()){
		int i=que.front();
		que.pop();
		for(int j=0;j<7;j++){
			if(vis[j]&&g[i][j]){
				vis[j]=false;
				que.push(j);
			}
		}
	}
	for(int i=0;i<7;i++)
		if(vis[i]) return false;
	return true;
}
int main()
{
	g[0][5]=g[0][1]=1;
	g[1][2]=g[1][0]=g[1][6]=1;
	g[2][1]=g[2][3]=g[2][6]=1;
	g[3][2]=g[3][4]=1;
	g[4][3]=g[4][5]=g[4][6]=1;
	g[5][4]=g[5][0]=g[5][6]=1;
	g[6][1]=g[6][2]=g[6][4]=g[6][5]=1;
		
	int res=0;
	for(int i=1;i<1<<7;i++){
		if(check(i))	res++;
	}
	cout<<res<<endl;
	return 0;
}

答案:80

试题F: 成绩统计 解法:模拟

【问题描述】
    小蓝给学生们组织了一场考试,卷面总分为100分,每个学生的得分都是一个0到100的整数。
    如果得分至少是60 分,则称为及格。如果得分至少为85分,则称为优秀。
    请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。
【输入格式】
    输入的第一行包含一个整数n,表示考试人数。
    接下来n行,每行包含一个0至100的整数,表示一个学生的得分。
【输出格式】
	输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分四舍五入保留整数。
【样例输入】
7
80
92
56
74
88
100
0
【样例输出】
71%
43%
【评测用例规模与约定】
	对于50%的评测用例,1≤n ≤100。
	对于所有评测用例,1≤n ≤10000。

#include<iostream>
#include<cmath>
using namespace std;
int n,pass,good;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        int t;
        cin>>t;
        if(t>=60) pass++;
        if(t>=85) good++;
    }
    double a=pass*100.0/n,b=good*100.0/n;
    cout<<round(a)<<"%"<<endl<<round(b)<<"%"<<endl;
    return 0;
}

试题G: 回文日期 解法:模拟+日期计算

【问题描述】
    2020年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为如果将这个日期按“yyyymmdd”的格式写成一个8位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。
    有人表示20200202是“千年一遇”的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202即2021年12月2日。
    也有人表示20200202并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同,因为大约100年后就能遇到下一个ABABBABA型的回文日期:21211212即2121年12月12日。算不上“千年一遇”,顶多算“千年两遇”。
    给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。
【输入格式】
    输入包含一个八位整数N,表示日期。
【输出格式】
    输出两行,每行1个八位数。第一行表示下一个回文日期,第二行表示下一个ABABBABA型的回文日期。
【样例输入】
20200202
【样例输出】
20211202
21211212
【评测用例规模与约定】
	对于所有评测用例,10000101 ≤ N ≤89991231,保证N是一个合法日期的8位数表示。
#include<iostream>
using namespace std;
int n,date1,date2;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int check(int x){
    int year=x/10000,month=x%10000/100,day=x%100;
    if(year%4==0&&year%100||year%400==0) days[2]=29;
    else days[2]=28;
    if(month<1||month>12||day<0||day>days[month]) return 0;
    int num[8];
    for(int i=0;i<8;i++) num[i]=x%10,x/=10;
    if(num[0]==num[2]&&num[1]==num[3]&&num[0]!=num[1]) return 2;
    return 1;
}
int get(int year){
    int month=0,day=0,x=year;
    for(int i=0;i<2;i++) month=month*10+x%10,x/=10;
    for(int i=0;i<2;i++) day=day*10+x%10,x/=10;
    return year*10000+month*100+day;
}
int main()
{
    cin>>n;
    for(int year=n/10000;!date2;year++){
        int t=get(year);
        if(t<=n) continue;
        int flag=check(t);
        if(flag>=1&&!date1) date1=t;
        if(flag>=2&&!date2) date2=t;
    }
    cout<<date1<<endl<<date2<<endl;
    return 0;
}

试题H: 子串分值和 解法:思维

【问题描述】
    对于一个字符串s,我们定义S的分值 f(S)为S中出现的不同的字符个数。例如f("aba") = 2,f("abc") = 3,f("aaa") = 1。
    现在给定一个字符串 S [0..n-1](长度为n),请你计算对于所有S的非空子串 S[i..j](0 ≤i≤ j <n),f(S[i..j])的和是多少。
【输入格式】
	输入一行包含一个由小写字母组成的字符串s。
【输出格式】
	输出一个整数表示答案。	
【样例输入】
ababc
【样例输出】
28		
【样例说明】
子串 f值
a     1
ab    2
aba   2
abab  2
ababc 3
 b    1
 ba   2
 bab  2
 babc 3
  a   1
  ab  2
  abc 3
   b  1
   bc 2
    c 1
【评测用例规模与约定】
	对于20%的评测用例,1≤n≤10;
	对于40%的评测用例,1≤n≤100;
	对于50%的评测用例,1≤n≤1000;
	对于60%的评测用例,1≤n≤10000;
	对于所有评测用例, 1≤n≤100000。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int N =1e5+10;
char s[N];
vector<int> v[26];
int main()
{
    scanf("%s",s);
    int len=strlen(s);
    for(int i=0;i<len;i++) v[s[i]-'a'].push_back(i);
    for(int i=0;i<26;i++) v[i].push_back(len);
    LL res=0;
    for(int i=0;i<26;i++){
        for(int j=0;j<v[i].size()-1;j++){
            res+=(LL)(v[i][j]+1)*(v[i][j+1]-v[i][j]);
        }
    }
    cout<<res<<endl;
    return 0;
}

试题I: 平面切分 解法:平面几何+思维

【问题描述】
	平面上有N条直线,其中第i条直线是y=Ai·x +Bi。请计算这些直线将平面分成了几个部分。
【输入格式】
	第一行包含一个整数N。
	以下N行,每行包含两个整数Ai,Bi。
【输出格式】
	一个整数代表答案。
【样例输入】
3
1 1
2 2
3 3
【样例输出】
6
【评测用例规模与约定】
	对于50%的评测用例,1≤N≤4, -10≤Ai,Bi≤ 10。
	对于所有评测用例,1≤N≤1000,-100000≤Ai,Bi≤100000。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
#define fi first
#define se second
const int N=1e3+10;
int n;
pair<int,int> a[N];
set<pair<double,double> > s;
int main()
{
    cin>>n;
    int res=1;
    for(int i=0;i<n;i++) cin>>a[i].fi>>a[i].se;
    sort(a,a+n);
    n=unique(a,a+n)-a;
    for(int i=0;i<n;i++){
        s.clear();
        for(int j=0;j<i;j++){
           if(a[i].fi==a[j].fi) continue;
           else{
               double x=(double)(a[j].se-a[i].se)/(a[i].fi-a[j].fi);
               double y=x*a[i].fi+a[i].se;
               s.insert(make_pair(x,y));
           }
        }
        res+=s.size()+1;
    }
    cout<<res<<endl;
    return 0;
}

试题J: 字串排序

【问题描述】
    小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
    在冒泡排序中,每次只能交换相邻的两个元素。
    小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
    例如,对于字符串lan排序,只需要1次交换。对于字符串qiao排序,总共需要4次交换。
    小蓝的幸运数字是V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
【输入格式】
	输入一行包含一个整数v,为小蓝的幸运数字。
【输出格式】
	输出一个字符串,为所求的答案。
【样例输入】
4
【样例输出】
bbaa
【样例输入】
100
【样例输出】
jihgfeeddccbbaa
【评测用例规模与约定】
	对于30%的评测用例,1<V≤20。
	对于50%的评测用例,1≤V≤100。
	对于所有评测用例, 1<V≤10000。

posted @ 2021-04-16 14:12  陌默丶  阅读(979)  评论(0)    收藏  举报