2021蓝桥杯模拟赛Java C组(四)


问题描述
请问在 1900 到 2020 中,有多少个质数。
思路解析
我是用gcd写的,用遍历math.sqrt也行
代码如下

public class test1 {
	public static void main(String[] args) {
		int count=0;
		for (int i = 1900; i < 2021; i++) {
			int sum=0;
			for (int j = 1; j < i; j++) {
				if (gcd(j, i)==1) {
					sum++;
				}
				if (sum==i-1) {
					count++;
				}
			}
		}
		System.out.println(count);//16
	}
	public static int  gcd(int a,int b) {
		return b==0?a:gcd(b, a%b);
	}
}


问题描述
  ASCII 码将每个字符对应到一个数值(编码),用于信息的表示和传输。在 ASCII 码中,英文字母是按从小到大的顺序依次编码的,例如:字母 A 编码是 65, 字母 B 编码是 66,字母 C 编码是 67,请编码为 80 的是哪个字母?
思路解析
不写代码也行
代码如下

public class test2 {
	public static void main(String[] args) {
		int a=80;
		char b=(char) a;
		System.out.println(b);//P
	}
}

问题描述
Fibonacci序列按照如下公式定义:
  F[1] = 1
  F[2] = 1
  F[i] = F[i-1] + F[i-2] (i>2)
  前几个 Fibonacci 数为 1, 1, 2, 3, 5, 8, 13, 21。
  请问,前100个 Fibonacci 数中,有多少个数是 3 的倍数?
思路解析
四个里有一个是3的倍数,写程序的话int装不下,要用long
代码如下

public class test3 {
	public static void main(String[] args) {
		long a=1;
		long b=1;
		int count=0;
		for (int i = 3; i <102 ; i++) {
			long c=0;
			c=a+b;
			a=b;
			b=c;
			if (a%3==0) {
				count++;
			}
		}
		System.out.println(count);//25
	}
}


问题描述
  有一棵二叉树,有2021个叶结点。
  请问。这棵树至少有多少个结点?
思路解析  
度为0的节点有2021个,度为2的节点比他少一个,度为1的节点没有节点最少

2021+2020=4041


问题描述
 一个身份证号码有 18 位数字或字母组成。其中前17位必须是数字,最后一位可能是数字或字母X。
  身份证号码满足一定的校验规则。
  令身份证号从右到左依次标号为 1 到 18,其中标号为 i 的位的位权设置为 2^(i-1) mod 11 (2的i-1次方除以 11 的余数)。
  将每一位的数值乘以位权后相加,得到的结果除以 11 的余数应当为 1。其中最后一位(标号为1)中如果出现字母 X,看成数字 10。
  例如,如果一个人的身份证号为 34052419800101001X,则:
  标号为 1 的位,位权 1,数值 X,即 10,相乘得 10。
  标号为 2 的位,位权 2,数值 1,相乘得 10。
  标号为 3 的位,位权 4,数值 0,相乘得 0。
  标号为 4 的位,位权 8,数值 0,相乘得 0。
  标号为 5 的位,位权 5,数值 1,相乘得 5。
  标号为 6 的位,位权 10,数值 0,相乘得 0。
  标号为 7 的位,位权 9,数值 1,相乘得 9。
  标号为 8 的位,位权 7,数值 0,相乘得 0。
  标号为 9 的位,位权 3,数值 0,相乘得 0。
  标号为 10 的位,位权 6,数值 8,相乘得 48。
  标号为 11 的位,位权 1,数值 9,相乘得 9。
  标号为 12 的位,位权 2,数值 1,相乘得 2。
  标号为 13 的位,位权 4,数值 4,相乘得 16。
  标号为 14 的位,位权 8,数值 2,相乘得 16。
  标号为 15 的位,位权 5,数值 5,相乘得 25。
  标号为 16 的位,位权 10,数值 0,相乘得 0。
  标号为 17 的位,位权 9,数值 4,相乘得 36。
  标号为 18 的位,位权 7,数值 3,相乘得 21。
  将乘积相加,得 199,除以 11 的余数正好为 1。
  小明的身份证号前 17 位为 11010120210221999,请问小明身份证的最后一位是多少?
答案提交
  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个字符,可能是数字或者大写字母X,在提交答案时只填写这个字符,填写多余的内容将无法得分。
思路解析
这题手算就行,当时怕算错写了程序,结果还是错了…
代码如下

public class test5 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		String n = sc.next();
		String[] str = n.split("");
		int arr[] =new int[str.length];
		for (int i = 0; i < str.length; i++) {
			arr[i]=Integer.parseInt(str[i]);
		}
		int sum=0;
		int len=arr.length-1;
		int i=2;
		while (len>=0) {
			sum+=(Math.pow(2, i-1)%11)*arr[len];
			len--;
			i++;
		}
		
		System.out.println(sum);//213
		// 220的11的倍数220-213+1=8
	}
}


问题描述
给定一个单词,请将这个单词的首字母大写,后面的所有字母小写。
思路解析
用toUpperCase,toLowerCase就行,不用自己写判断转化
代码如下

public class test6 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		String s = sc.next();
		String[] str = s.split("");
		for (int i = 0; i < str.length; i++) {
			if (i==0) {
				System.out.print(str[i].toUpperCase());
			}else {
				System.out.print(str[i].toLowerCase());
			}
		}
	}
}


问题描述
小Hi的公司经常举办回馈社会的爱心活动。这次小Hi作为志愿者带领社区的孩子们参观了青少年天文馆。他发现孩子们对于摩尔斯电码非常感兴趣。
摩尔斯电码由两种基本的信号组成:短信号"滴"(用字符’.‘表示)以及长信号"嗒"(用字符’-'表示)。下图是数字0-9的摩尔斯电码表示,每个数字都由5个字符组成:
.---- …— …-- …- … -… --… —… ----. -----
1 2 3 4 5 6 7 8 9 0
为了让孩子们开心,小Hi决定把每位孩子的生日日期转化为摩尔斯码赠送给他们。例如日期20210101对应的摩尔斯电码是:
…— ----- …— .---- ----- .---- ----- .----
你能写一个程序帮助小Hi吗?

思路解析
没什么好说的,一共十种字符串,存到数组再操作就行了
代码如下

public class test6 {
	public static void main(String[] args) {
		int arr[]= {0,1,2,3,4,5,6,7,8,9};
		String str[]= {"-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
		Scanner sc=new Scanner(System.in);
		int n = sc.nextInt();
		String[] st=new String [n];
		for (int i = 0; i < n; i++) {
			int s = sc.nextInt();
			String s1=s+"";
			st[i]=s1;
			
		}
		for (int i = 0; i < st.length; i++) {
			String[] split = st[i].split("");
			
			for (int j = 0; j < split.length; j++) {
				int a = Integer.parseInt(split[j]);
				for (int k = 0; k < 10; k++) {
					if (arr[k]==a) {
						System.out.print(str[k]+" ");
					}
				}
			}
			System.out.println("");
		}
	}
}


问题描述
 小蓝在商店买文具。
  一支钢笔 x 元,小蓝买了 a 支。
  一个笔记本 y 元,小蓝买了 b 本。
  请问,小蓝一共需要支付多少钱?
思路解析
这题不说了吧,出题人当时怎么想的???


问题描述
 给定一个序列 S = (s[1], s[2], …, s[n]),一个位置 p 上的变化度是指以这个位置为中心的相邻的 5 个元素的最大值与最小值的差,即 s[p-2], s[p-1], s[p], s[p+1], s[p+2] 中最大值与最小值的差。
  一个序列总共有 n-4 个变化度,位置 1, 2, n-1, n 没有变化度。
  例如,对于下面的序列 (1, 0, 4, 8, 5, 7, 6),总共有 3, 4, 5 三个位置有变化度,分别为 8, 8, 4。
  给定一个序列,请求出这个序列的变化度。
对于所有评测用例,5 <= n <= 1000,0 <= s[i] <= 1000000。
思路解析
按照题目思路即可,不会超时
代码如下

public class test8 {
	static int arr[];
	static int arrcy[];
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n = sc.nextInt();
		arr=new int[n];
		arrcy=new int[n-4];
		for (int i = 0; i < n; i++) {
			arr[i]=sc.nextInt();
		}
		for (int i = 2; i < n-2; i++) {
			arrcy[i-2]=result(i);
		}
		for (int i = 0; i < arrcy.length; i++) {
			System.out.print(arrcy[i]+" ");
		}
	}
	public static int result(int a) {
		int max;
		int min;
		if (arr[a-2]<=arr[a-1]) {
			min=arr[a-2];
			max=arr[a-1];
		}else {
			min=arr[a-1];
			max=arr[a-2];
		}
		for (int i = 0; i < 3; i++) {
			if (arr[a+i]<min) {
				min=arr[a+i];
			}
			if (arr[a+i]>max) {
				max=arr[a+i];
			}
		}
		return max-min;
	}
}


问题描述

小Hi正在研究一种特殊的栈。这种栈的元素既可以从栈顶出栈,也可以从栈底出栈。(进栈还是只能从栈顶进栈)
  已知入栈的序列是1~N的一个排列,请你判断出栈序列能否是1, 2, 3, … N?
思路解析
当时不理解题目,以为是全部入栈后再出栈,其实题目的意思是,每个元素入栈后判断是否能出栈,也就是一边入栈,一边出栈,最终判断能否按1-n的顺序出栈,思路写在代码注释
另外check方法使用了递归,不确定是否会超时
代码如下

public class test9 {
	static int start;
	static int end;
	static int k;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int T = sc.nextInt();
		//用List存储T个数组
		List<int []> ls=new ArrayList<int []>(); 
		for (int i = 0; i < T; i++) {
			int N = sc.nextInt();
			int arr[]=new int[N];
			for (int j = 0; j < N; j++) {
				arr[j]=sc.nextInt();
			}
			ls.add(arr);
		}
		//将List中的各个数组进行处理
		for (int i = 0; i < ls.size(); i++) {
			//start:当前栈中的第一个元素下标
			start=0;
			//end:当前栈中的最后一个元素下标
			end=-1;
			//k:当前应该出栈的元素的值
			k=1;
			//用来处理的数组
			int [] x=new int[ls.get(i).length];
			//依次入栈
			for (int j = 0; j < ls.get(i).length; j++) {
				//入栈完成,end+1;
				end++;
				x[end]=ls.get(i)[j];
				//判断是否需要出栈
				check(x);
			}
			//出栈完成输出结果
			if (end<start) {
				System.out.println("YES");
			}else {
				System.out.println("NO");
				
			}
		}
		
	}
	public static void check (int x[]) {
		
		if (x[start]==k) {
			start++;
			k++;
			//出栈后再次判断
			check(x);
		}
		if (x[end]==k) {
			if (start!=end) {
				end--;
				k++;
				//出栈后再次判断
				check(x);
			}
		}
		return;
	}
}

十一


问题描述

给定一个序列 (a_1, a_2, …, a_n), 定义序列中的一个递增三元组是指三个下标 i, j, k 对应的三个元素 a_i, a_j, a_k,这三个元素满足 a_i < a_j < a_k。
  例如序列 (1, 1, 4, 3, 2, 4) 有以下 4 个递增三元组:
  1. 下标 1, 4, 6 对应的 1, 3, 4;
  2. 下标 1, 5, 6 对应的 1, 2, 4;
  3. 下标 2, 4, 6 对应的 1, 3, 4;
  4. 下标 2, 5, 6 对应的 1, 2, 4。
    注意,可能有下标不同但对应数值相同的三元组,他们应当算成不同的三元组。
  给定序列,请问序列中一共有多少个不同的递增三元组。
输入格式
  输入第一行包含一个整数 n,表示序列的长度。
  第二行包含 n 个整数 a_1, a_2, …, a_n,表示给定的序列。
输出格式
  输出一行,包含一个整数,表示序列中的递增三元组数量。请注意答案可能很大,可能超过 32 位二进制整数的范围,建议使用 64 位二进制整数。

思路解析
暂时只能想到枚举,会超时
代码如下

public class test10 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n = sc.nextInt();
		int arr[]=new int[n];
		for (int i = 0; i < n; i++) {
			arr[i]=sc.nextInt();
		}
		long count=0;
		//枚举法
		for (int i = 0; i < n; i++) {
			for (int j = i+1; j < n; j++) {
				for (int j2 = j+1; j2 < n; j2++) {
					if (i<j&&j<j2) {
						if (arr[i]<arr[j]&&arr[j]<arr[j2]) {
							count++;
						}
					}
				}
			}
		}
		System.out.println(count);
		
		
	}
}

十二


问题描述
 给定两个序列 A=(a_1, a_2, …, a_n) 和 B=(b_1, b_2, …, b_m), 它们的一个公共子序列是指从两个序列中分别取出相同个数的元素,按照原来的顺序排列后,对应位置的数值相等。
  例如,对于序列 A=(3, 2, 7, 6, 7) 和 B=(2, 3, 5, 7),可以在序列 A 中取出第 2, 3 个元素,在序列 B 中取出第 1, 4 个元素,值都是 2, 7,因此 2, 7 是一个公共子序列,在 A 中取第 2, 3 个元素和在 B 中取 1, 4 个元素是这个公共子序列的一种取法。
  在这两个序列中,有 4 中取法可以取出长度为 2 的公共子序列,例如
  1. 在 A 中取第 1, 3 个元素,在 B 中取 2, 4 个元素;
  1. 在 A 中取第 1, 5 个元素,在 B 中取 2, 4 个元素;
  1. 在 A 中取第 2, 3 个元素,在 B 中取 1, 4 个元素;
  1. 在 A 中取第 2, 5 个元素,在 B 中取 1, 4 个元素。
  给定两个序列,请问有多少种取法可以取出长度为 k 的公共子序列。

输入格式

输入第一行包含三个整数 n, m, k,分别表示序列 A 的长度、序列 B 的长度和公共子序列的长度。
  第二行包含 n 个整数 a_1, a_2, …, a_n,表示给定的 A 序列。
  第三行包含 m 个整数 b_1, b_2, …, b_m,表示给定的 B 序列。

输出格式

输出一行,包含一个整数,表示长度为 k 的公共子序列的数量,答案可能很大,请输出答案除以 1000007 的余数。

思路解析
同样是枚举(循环嵌套比较多,debug了一下午)
代码如下

public class test12 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int [] arr1=new int[n];
		int [] arr2=new int[m];
		for (int i = 0; i < arr1.length; i++) {
			arr1[i]=sc.nextInt();
		}		
		for (int i = 0; i < arr2.length; i++) {
			arr2[i]=sc.nextInt();
		}
		
		
		long sum=0;//记录总数
		long count=0;
		int len;
		if (k==1) {
			len=1;
		}else {
			len=arr1.length;
		}
		for (int x = 0; x < len; x++) {
			int b=0;
			for (int i = x; i < arr1.length; i++) {
				for (int j = b; j < arr2.length; j++) {
					//找到一对数字
					if (arr1[i]==arr2[j]) {
						count++;
						//找到一个序列
						if (count==k) {
							sum++;
							//找到后记录,然后count--,继续找后面是否有满足要求的数
							count--;
						}else {
							//记录下标,下次从这里找
							b=j+1;
							break;
						}
					}
				}
			}
			count--;
		}
		System.out.println(sum%1000007);
	}
}

非暴力枚举解法等会了再补
评论区欢迎指正

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值