蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)

1.试题A:完美车牌 5’
描述
有一些数字可以颠倒过来看,例如0、1、80、1、8颠倒过来还是本身,66颠倒过来是99,99颠倒过来看还是66,其他数字颠倒过来不构成数字。

类似的,一些多位数也可以颠倒过来看,比如106106颠倒过来是901901.

假设某个城市的车牌只由66位数字组成,每一位都可以取00到99。请问这个城市最多有多少个车牌180°180°倒过来恰好还是原来的车牌?

例如:车牌号:886988886988,倒过来还是886988886988

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个数字,填写多余的内容将无法得分。

Python语言选手
print(“你的答案”)

C/C++语言选手
#include

int main()

{

printf("你的答案");

return 0;

}

Java语言选手
public class Main{
public static void main(String[] args){
System.out.println(“你的答案”);
}
}

一共有6个空。
我们先看最外层的1, 6层怎么填。
因为要满足反转,所以我们要考虑反转后一定要对称。
那么我们可以选择 (0,0)(1, 1)(8, 8)(6, 9)(9, 6)
再考虑2, 5层 同样有 这五种情况。
3,4层 同样。
具有对称性
那么根据排列组合。一共有5 * 5 * 5 = 125种情况。
————————————————
版权声明:本文为CSDN博主「是水还是流年」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43960370/article/details/104447932

代码(C实现)

#include
int main()
{
     
    int  a[10];
   a[0] = 1;
   a[1] = 1;
   a[2] = 0;
   a[3] = 0;
   a[4] = 0;
   a[5] = 0;
   a[6] = 1;
   a[7] = 0;
   a[8] = 1;
   a[9] = 1;
    int count = 0;
    for(int i = 0; i < 10; i++)
    {
     
        
        for(int j = 0; j < 10; j++)
        {
     
           

            for(int k = 0; k < 10; k++)
            {
     
                if(a[i] == 1 &&a[j] == 1 && a[k] == 1)count ++;

            }
        }
    }
    printf("%d",count);
    return 0;
}


  1. 试题B:完美日期 5’
    描述
    【问题描述】

    不知天上宫阙,今夕是何年。

    对于完美日期yyyy/mm/dd,wlxsq的定义是:

年月日中均没有出现数字4,
年月日的数位之和是8的倍数
例如:2020/02/02 就是一个完美日期,没有出现数字4,且数位之和是8的倍数。

wlxsq想知道从2020/02/22开始,第88个完美日期是哪个?

【答案提交】

   这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个格式yyyy/yy/dd,在提交答案时直接填写这个日期,注意需要如果答案有前导零则不能忽略,填写多余的内容将无法得分。

模拟即可。
到每一月的月末,就变到新的一月。
到每一年的年末,就变到新的一年。
注意判断一下闰年的
22
2月份是
2929
29天即可。
答案:
2022/03/072022/03/07
2022/03/07

代码:

#include
int dx[]={
     0,31,29,31,30,31,30,31,31,30,31,30,31};
bool check(int x){
     
	if( x % 400 == 0) 
	    return true;
	else if( x % 4 ==0 && x % 100 != 0)
	    return true;
	else 
	    return false;
}

int p(int x,int y,int z){
     
	int res = 0;
	int flag = 1;
	while( x > 0){
     
		res += x % 10;
		if( x % 10 == 4) flag = 0;
		x /= 10;
	}
	while( y > 0){
     
		res += y % 10;
		if( y % 10 == 4) flag = 0;
		y /= 10;
	}
	while( z > 0){
     
		res += z % 10;
		if( z % 10 == 4) flag =0;
		z /= 10;
	}
	if( flag && res % 8 == 0)  return 1;
	else 
	   return 0;
}

int main(){
     
	int x,y,z;
	int ans = 0;
	x = 2020; y = 2 ; z = 22;
	while(ans < 88){
     
		z++;
		if(check(x) && y==2){
     
			if( z > 28){
     
				z = 1;
				y++;
			}
		}
		else if( z > dx[y]){
     
			z = 1;
			y++;
		}
		if( y > 12){
     
			x++;
			y = 1;
		}
		if(p(x,y,z)){
     
			ans++;
			printf("%d %d %d\t%d\n",x,y,z,ans);
		}
	}
return 0;
}

3.C. 试题C:天机锁10’
描述
【问题描述】
天机锁,锁天机~
wlxsq在机缘巧合的情况下就获得一把天机锁。wlxsq迫不及待的想打开这把锁。该锁的密码是由八个数字构成的,每个数字都是[0,9]中的一个~
锁上面写道:
水(数字9)火(数字4)相生相克,同现同隐(要么都出现,要么都不出现),数量一致(且出现则数量得一样多)。
土(数字2)乃大地,为伊始(数字2一定出现)。
世间万物,不过五二(八个数字之和不超过52)。
此乃天机,一日一次之~
由于天机锁一天只能试一次,wlxsq想知道,总共有多少种方案~

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个数字,在提交答案时直接填写这个数字,填写多余的内容将无法得分。
方法一:
8个
for循环,枚举所有的情况,逐一判断即可~
方法二:
8个坑,
dfs一遍,对于每一种情况逐一判断即可。
答案:
19811435

代码(C实现):

#include
int a[10];
typedef long long ll;
const int M = 0x7fffffff;
ll ans = 0;

void print(){
     
	for(int i = 1; i <= 8; i++)
	   printf("%d ",a[i]);
	printf("\n");
}

bool check(){
     
	int flag = 0;
	int x = 0, y = 0;
	int sum = 0;
	for(int i = 1; i <= 8; i++){
     
		sum += a[i];
		if(a[i] == 2)
		    flag = 1;
		else if( a[i] == 9)
		    x++;
		else if( a[i] == 4)
		    y++;
	}
	if( flag && x==y && sum<=52)
	    return true;
	else
	    return false;
}

void dfs(int i){
     
	if( i > 8){
     
		if(check()){
     
			ans++;
			if( ans > 100 && ans < 120)
			    print();
		}
		return;
	}
	for(int j = 0; j < 10; j++){
     
		a[i] = j;
		dfs(i + 1);
		
	}
}

int main()
	{
     
	dfs(1);
    printf("%d",ans);
	return 0;
}

4.完美运算 10‘
描述
定义a1:表示数字A对应的三进制数位中1的个数
定义a2:表示数字A对应的三进制数位中2的个数
定义完美运算A○B,如果∣a1−a2∣=∣b1−b2∣,A○B的值为1,否则为0.请问,在[1,2020] 区间,有多少对
(A,B)的结果为
1
例如:A=2,B=3则
a1=0,a2=1,b1=1,b2=0,满足
∣a1−a2∣=∣b1−b2∣所以
A○B的结果为1。
注意,
A=2,B=3构成的数对(2,3)与
A=3,B=2构成的数对(3,2)算同一对。
更新:(2,2)也算一对哦~
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
枚举所有的数字A和所有的数字B。
然后将这两个数转成三进制,计算出a1和a2的值。
答案:
472701
代码(C实现):

#include
#include
typedef long long ll;
ll a[2050],b[2050];
void p(){
     
	for(int i = 1; i <= 2020; i++){
     
		int m = i;
		while( m > 0){
     
			if( m % 3 == 1) 
			    a[i]++;
			else if( m % 3 == 2)
			    b[i]++;
			m /= 3;
		}
	}
}

int main(){
     
	p();
	ll ans = 0;
	for(int i = 1; i <= 2020; i++){
     
		for(int j = i; j <= 2020; j++){
     
			if( abs(a[i]-b[i]) == abs(a[j]-b[j])){
     
			    ans++;
				if( ans < 10) 
				    printf("%d",i+" ""%d",j );
			}
		}
	}
printf("%d",ans);

	return 0;
}

5.试题E:三叉神树 15’
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第1张图片
图1
给定如图1所示三叉树,节点A为根节点,E,F,J,K,H,L为叶子节点。已知这12个节点的权值对应着数字[1,12],使得所有以非叶子节点为根的子树权值之和为偶数。

如下图2所示,为其中一种满足要求的方案。

图2样例解释:

对于非叶子节点B:3 + 1 = 4
对于非叶子节点C:5 + 11 + 9 + 7 + 2 = 34
对于非叶子节点G:9 + 7 + 2 = 18
对于非叶子节点D:10 + 8 + 6 + 4 = 28
对于非叶子节点I:6 + 4 = 10

请求出所有满足条件的方案数!!
叶子节点:一棵树当中没有子结点(即度为0)的结点称为叶子结点
【答案提交】
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第2张图片
图2
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include
typedef long long ll;
int a[15];
int vis[15];
ll ans = 0;

void print(){
     
	for(int i = 1; i <= 12; i++)
	    printf("%d ",a[i]);
	printf("\n");
}

bool check(){
     
	int x = a[2] + a[5];
	if( x % 2 == 1)
	    return false;
	x = a[7] + a[8] + a[9];
	if( x % 2 == 1)
	    return false;
	x += a[6] + a[3];
	if( x % 2 == 1)
	    return false;
	x = a[11] + a[12];
	if( x % 2 == 1)
	    return false;
	x += a[4] + a[10];
	if( x % 2 == 1)
	    return false;
	return true;
}

void dfs(int i){
     
	if( i > 12){
     
		if(check()){
     
			ans++;
			if(a[1] == 12 && a[2] == 3 && a[5] == 1)
			   print();
		}
		return ;
	}
	for(int j = 1; j <= 12; j++){
     
		if(!vis[j]){
     
			a[i] = j;
			vis[j] = 1;
			dfs(i + 1);
			vis[j] = 0;
		}
	}
}

int main(){
     
	dfs(1);
	printf("%d",ans);

	return 0;
}

6.试题F:JM斗牛 17’
描述
JM打完麻将,觉得太简单了,所以决定去斗牛,挑战一下高难度。
一副牌共54张牌,即采用牌大王(1张),小王(1张),K,Q,J,10,9,8,7,6,5,4,3,2,A。除了大小王,其余牌型均为4张。故4*13+2=54张
斗牛则是每人5张牌,计算5张牌的构成的点数,然后比较点数大小。
关于点数计算:
大王(S),小王(S),K,Q,J都当成是10点,A当成是1点,其余牌都当其本身的点数。 大王,小王均用大写字母S表示
每位玩家5张牌,玩家用手上任意的3张牌组合(且只能用3张牌组成10的倍数),使其点数之和为10的倍数,这样就称之为“牛”。
然后将剩余的2张牌点数之和取个位数,如这2张牌之和也为10的倍数,则组成“牛牛”牌型。如这2张牌之和不为10的整数倍,则去掉十位数之后个位数为几,则成为“牛几”牌型。
如任意三张牌组合的点数之和都不能成为10的倍数,则称之为“无牛”牌型。
例如:
牛牛牌型:选取的3张牌之和为10的整数倍,余下2张牌之和也为10的整数倍。例:A,9,10,J,Q.选取(A,9,J)和为10的整数倍,(10,Q构成)牛牛
牛九牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为9。例:A,9,10,J,9。   
牛八牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为8。例:A,9,10,J,8。
牛七牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为7。例:A,9,10,J,7。选取(A,9,J)和为10的整数倍,(10,7构成)牛七
无牛牌型: 任意选取的3张牌之和均不可能为10的整数倍例:A,9,8,9,7。
JM会打麻将,但是不怎么会斗牛,想请你帮忙编写程序帮忙计算一下,JM 拿到的牌是什么牌型。
输入
输入一行包含5个字符,表示5张牌。
输出
输出一行表示牌型。数字1~9表示牛一至牛九,如果是牛牛牌型,则输出“so cool!”,如果是无牛排序,则输出“so sad!”
样例
输入
复制
A 2 3 5 S
输出
复制
1
输入
复制
S S A 8 8
输出
复制
so sad!
输入
复制
S S J Q K
输出
复制
so cool!

答案:首先,我们证明答案是唯一的:
对于
J,Q,K,S都转换称数字
10,记这5张牌的点数分别为
a1,a2…a5
,记录
sum=∑i=15ai
记录答案为牛x牌型。牛牛牌型其实就是牛0牌型。
如果存在i,j,k,使得ai+aj+ak为10的倍数,那么
x=(sum−ai−aj−ak)%10,所以x其实就是x%10
所以答案唯一。
其次,我们可以枚举所有可能的三元组(i,j,k),判断这三张牌点数之和是否为10的倍数即可。
5个数全排列一下就可以了~
代码(C实现):

#include
#include
#define N 100
int bag[N]={
     0};
int book[N]={
     0};
int n=5;
int flag=0;
int max0=0;
void dfs(int num,int sum ){
     
	if( num==4 ){
     
		if( sum%10==0 ){
     
			flag=1;
			int k,ss=0;
			for( k=1;k<=n;k++ ){
     
				if( book[k]==0)
						ss+=bag[k];
			}
			
			if( ss%10==0 )
			  max0=100;
			
			if( ss%10>max0 )
			max0=ss%10;
		}
		
		return ;
	}
	
	int i;
	for( i=1;i<=n;i++  ){
     
		
		if( book[i]==1 )
		continue;
		
		book[i]=1;
		
		dfs( num+1,sum+bag[i]);
		
		book[i]=0;
		
	}
	return ;
}
int main(){
     

    int i,j,k;
	char s[N];
	gets( s );
	int cnt=1;
	for(i=0;i<strlen(s);i++){
     
		if( s[i]==' '||s[i]=='0')
		continue;
		if( s[i]=='1'&&s[i+1]=='0'){
     
		bag[cnt++]=10;
		continue;
	    }
		if( s[i]=='A'){
     
			bag[cnt++]=1;
			continue;
		}
		if( s[i]=='K'||s[i]=='Q'||s[i]=='J'||s[i]=='S'){
     
			bag[cnt++]=10;
			continue;
		}
		bag[cnt++]=s[i]-'0';
	}
	dfs( 1,0 );
	if( flag==0 ){
     
		printf("so sad!");
	
	}else{
     
		
		if( max0==100 )
		printf("so cool!");
		else
		printf("max0");
	}
	
	return 0;
}

7.试题G:JM boy 去爬山 18’
描述
疫情终于终于得到了一定的控制~
JM boy在家宅了又宅,宅了又宅,总算是可以带上口罩出去爬山运动了~
JM boy在爬完山之后,发现自己爬的山像及了一个数列。山是有山峰山谷的,而数列也是可以定义山峰山谷的。
例如,对于某n个数的一种排列,如果不存在任意的i使得
Ai>Ai+1 JM boy想知道,对于1……n的n个数的数列,该数列有多少种排列是属于山峰排列的。
当然,对于n=1及n=2的情况,肯定是所有的排列都属于山峰排列了。
输入
输入一个整数n,表示数列元素的个数。
输出
输出山峰排列的个数。
样例
输入
复制
1
输出
复制
1
输入
复制
3
输出
复制
4
提示
【样例2解释】
共有以下4种方案: 123、132、231、321
【数据规模】
对于60%的数据 n <= 10
对于100%的数据 n <= 60
答案:思路一:
对于小数据60%,直接全排列所有方案,然后再逐一判断每一种方案的是否满足条件~
打印出<=10数据,可以发现,答案为2^{n-1}
思路二:
假设山峰数字为x,除了x的所有的数字,都有两种选择,要么x的左边,要么在x的右边,确定左右之后,所有数字的排列固定,显然答案为2^{n-1}。

代码(C实现):

#include
typedef  long long ll;
int read(){
     
	int f = 1;
	int x = 0;
	char ch = getchar();
	while( ch <'0' || ch>'9'){
     
		if( ch == '-')
		   f = -1;
		ch = getchar();
	}
	while( ch >='0' && ch<='9'){
     
		x = x*10 + ( ch - '0');
		ch = getchar();
	}
	return x;
} 
int main(){
     
	int n;
	n = read();
	if(n == 1){
     
		printf("1\n");
		return 0;
	}
	ll ans = 1;
	for(int i = 2; i <= n; i++)
	    ans *= 2;
	printf("%lld\n",ans);
	return 0;
}

8.试题H:宝剑锋从磨砺出 20’
描述
幸运的wlxsq偶得一块上古神铁!wlxsq决定将其锻造成一把攻击力不小于K的神器!
wlxsq跋山涉水,耗费巨资请来了锻造大师JM boy,在JM boy的手上,任何材料都能发挥到最大价值~
wlxsq同样耗费巨资提前准备了N个材料。每一次对上古神铁进行锻造都需要选择一个材料配合进行锻造。对于每一个材料i,有两种方式能够配合上古神铁进行锻造:
1、材料i作为辅助,配合三味真火进行锻造,可增加攻击力P1​,材料i可重复使用。
2、材料i直接和上古神铁融合,增加攻击力P2,融合后材料i则不能再被使用了。
由于锻造大师JM boy锻造神器是通过锻造次数来收取费用的。由于wlxsq之前的耗费巨资,导致现在wlxsq资金紧张,wlxsq想知道,他最少需要请JM boy锻造几次,才能够把锻造出攻击力不小于K的一把神兵利器,你能帮帮wlxsq吗?
输入
第一行输入两个整数
N,K,分别表示材料的个数以及攻击力K。
接下来输入N行,每行两个数
Pi1,Pi2,表示每个材料对应的方式1,方式2所能够代来的攻击力提升。
输出
输出最少锻造次数
样例
输入
复制
1 10
3 5
输出
复制
3
输入
复制
2 10
3 5
2 6
输出
复制
2
提示
【样例1解释】
前两次使用材料1通过方式1进行锻造,第三次使用材料1通过方式2进行锻造。共获得
3+3+5=11攻击力
【样例2解释】
分别使用材料1,材料通过方式2进行锻造,共获得
5+6=11攻击力
【数据规模】
对于100%的数据
N≤105,K≤109,1≤P1≤P2≤10^9
**答案:考虑贪心。
答案一定是选一些方式1和一些方式2构成的。
那么如果确定了选择方式1和方式2的个数,那么我们一定会选择方式1中权值最大的那个值,以及方式2中权值前k的值之和。
所以,我们将所有方式1从大到小排序,所有方式2从大到小排序。
枚举即可。
复杂度O(nlogn)
**
代码(C++实现):

#include
using namespace std;

typedef struct{
     
	int v;
	int now;
}node;

node p[200005];

bool cmp(node a,node b){
     
	return a.v > b.v ;
}

int main(){
     
	int n,k;
	scanf("%d %d",&n,&k);
	for(int i = 0; i < n; i++){
     
		scanf("%d %d",&p[2*i].v,&p[2*i+1].v);
		p[2*i].now = 0;
		p[2*i+1].now = 1;
	}
	sort(p, p + 2*n, cmp);
	int i = 0;
	int ans = 0;
	while( k > 0){
     
		if(p[i].now == 1){
     
			k -= p[i].v ;
			i++;
			ans++;
		}
		else{
     
			ans += k / p[i].v ;
			if( k % p[i].v != 0) ans++;
			k = 0;
		}
	}
	printf("%d\n",ans);
	return 0;
}

9.由于疫情缘故,wlxsq家里还剩下超多年货,没有吃完。
为了简化问题,假设wlxsq家里还剩N种年货,每种年货Ai包,同一种年货中每一包都是一样的。
现在wlxsq准备返杭了,他想从N种年货中挑不超过K包年货带返杭。wlxsq想知道他总共有多少种选择方案?
输入
第一行输入两个整数N,K,含义如题目描述。
第二含输入N个整数 Ai,表示每一种年货的数量。
输出
输出总共方案数,结果对998244353取模。
样例
输入
复制
3 1
2 2 2
输出
复制
4
输入
复制
8 13
1 2 3 4 5 6 7 8
输出
复制
65044
提示
【样例1解释】
总共有4种方案,对应每一种年货的选择如下:(1,0,0),(0,1,0),(0,0,1),(0,0,0)
【评测用例规模与约定】
对于40%的数据,2<=N<=10,
对于100%的数据,2<=N<=1000,Ai,K<=10^5
答案:
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第3张图片
能力有限,代码不会

10.试题J:梅深不见冬25’
描述
Let’s have some music~
结合音乐做此题,效果更佳~
《梅深不见冬》
风,吹起梅岭的深冬;霜,如惊涛一样汹涌;雪,飘落后把所有烧成空,
像这场,捕捉不到的梦。
醒来时已是多年之久,宫门铜环才长了铁锈,
也开始生出离愁。
——银临《梅深不见冬》
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第4张图片
wlxsq在深冬的梅岭中走着,感到十分寒冷,也感到十分孤独。这时他看到前方有一座小屋,透过窗户,他看见里面有一座火炉,如图:
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第5张图片
正巧,屋内的主人在家里。wlxsq想要进屋内暖和暖和。于是,他敲了敲门,主人热情的开了门。
wlxsq:您好,我能进您屋内取取暖吗?
主人:好的。但是我有一个条件。
wlxsq:什么条件?

蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第6张图片
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第7张图片
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第8张图片
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第9张图片
思路:
蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现)_第10张图片
能力有限,代码不会!!!

你可能感兴趣的:(蓝桥杯模拟赛2(大学生组&青少年组)赛后试题解析(C实现))