第十一届蓝桥杯模拟赛JAVA题解

欢迎指出错误,共同学习!

 

一、问题描述

一个数被称为质数(或素数)是指除开1和它本身两个约数外,没有其他的约数。
在不超过10000的数中,一共有多少个质数?

1229

二、问题描述

1200000有多少个约数(只计算正约数)。

96

三、问题描述 

将LANQIAO中的字母重新排列,可以得到不同的单词,如LANQIAO、AAILNOQ等,注意这7个字母都要被用上,单词不一定有具体的英文意义。
请问,总共能排列如多少个不同的单词。

全排列   答案:2520
public class Main{
	static Set<String>set = new HashSet<>();
	static StringBuilder sb = new StringBuilder("LANQIAO");
    public static void main(String []args){
    	dfs(0);
    	System.out.println(set.size());
    }
    static void dfs(int idx) {
    	if(idx == sb.length()) {
    		set.add(sb.toString());
    		return;
    	}
    	for(int i = idx;i < sb.length();i ++) {
    		char t = sb.charAt(i);
    		sb.setCharAt(i, sb.charAt(idx));
    		sb.setCharAt(idx, t);
    		
    		dfs(idx+1);
    		
    		t = sb.charAt(i);
    		sb.setCharAt(i, sb.charAt(idx));
    		sb.setCharAt(idx, t);
    	}
    }
}

四、问题描述 

一个包含有2019个结点的二叉树,最少有多少层?
注意当一棵二叉树只有一个结点时为一层。

求最少,则构建一棵完全二叉树,第i层最多有2^(i-1)个节点,算一下就知道了
答案: 10

五、问题描述 

给定一个单词,请使用凯撒密码将这个单词加密。
凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移3位后被替换成密文。即a变为d,b变为e,...,w变为z,x变为a,y变为b,z变为c。
例如,lanqiao会变成odqtldr。
输入格式:
  输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式:
  输出一行,表示加密后的密文。
样例输入:
lanqiao
样例输出:
odqtldr
评测用例规模与约定:
  对于所有评测用例,单词中的字母个数不超过100。
 

import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		for(int i = 0;i < s.length();i ++) {
			char c = s.charAt(i);
			if(c <= 'w') {
				System.out.print((char)(c+3));
			}else if(c == 'x'){
				System.out.print('a');
			}else if(c == 'y'){
				System.out.print('b');
			}else if(c == 'z'){
				System.out.print('c');
			}
		}
	}
}

六、问题描述 

小明非常不喜欢数字 2,包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2,小明将它称为洁净数。
请问在整数 1 至 n 中,洁净数有多少个?
输入格式:
  输入的第一行包含一个整数 n。
输出格式:
  输出一行包含一个整数,表示答案。
样例输入:
30
样例输出:
18
评测用例规模与约定:
  对于 40% 的评测用例,1 <= n <= 10000。
  对于 80% 的评测用例,1 <= n <= 100000。
  对于所有评测用例,1 <= n <= 1000000。
 

import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int ans = 0;
		int n = sc.nextInt();
		for(int i = 1;i <= n;i ++) {
			if(check(i)) {
				ans ++;
			}
		}
		System.out.println(ans);
	}
	static boolean check(int num) {
		while(num != 0) {
			int t = num % 10;
			if(t == 2) {
				return false;
			}
			num /= 10;
		}
		return true;
	}
}

 

七、问题描述 

输入一个单词,请输出这个单词中第一个出现的元音字母。
元音字母包括 a, e, i, o, u,共五个。
输入格式:
  输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式:
  输出一行包含一个字母,为单词中第一个出现的元素字母。若单词中不存在元音字母,输出字母n。
样例输入:
hello
样例输出:
e
样例输入:
fly
样例输出:
n
评测用例规模与约定:
  对于所有评测用例,单词中的字母个数不超过100。

 

import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		for(int i = 0;i < s.length();i ++) {
			char c = s.charAt(i);
			if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
				System.out.println(c);
				return;
			}
		}
		System.out.println("n");
	}
}

八、问题描述 

小明开了一家花店,这天,有个客户定了非常多的花,按客户的需要,这些花要排成 n 行 m 列。
小明要将这些花运送到客户那,然而由于花太多,需要分两辆车才能装下。
小明怕自己弄错花的顺序,因此在分车的时候,他准备将前面一些列(注意不是行)的花放在第一辆车上,将其实的花放在第二辆车上。
已知每盆花的重量,要使第一辆车和第二辆车尽可能总重量一致,请帮助小明分装这些花,请告诉小明两辆车的重量最小差多少。
输入格式:
  输入的第一行包含两个整数 n, m,分别表示行数和列数。
  接下来 n 行,每行 m 个正整数,分别表示每盆花的重量。
输出格式:
  输出一个整数,表示总重量最接近时两车的重量之差(的绝对值)。
样例输入:
3 4
1 2 3 9
5 6 7 8
2 3 4 9
样例输出:
7
样例说明:
  将前 3 列放一辆车,后 1 列放一辆车,第一辆比第二辆重 7 。
评测用例规模与约定:
  对于 30% 的评测用例,2 <= n, m <= 20。
  对于 70% 的评测用例,2 <= n, m <= 100。
  对于所有评测用例,2 <= n, m <= 1000,每盆花的重量不超过 1000。
 

import java.util.*;
public class Main{
	static int[]arr = new int [1005];
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int sum = 0;
		for(int i = 1;i <= n;i ++) {
			for(int j = 1;j <= m;j ++) {
				int num = sc.nextInt();
				arr[j] += num;
				sum += num;
			}
		}
		int L = 0,ans = Integer.MAX_VALUE;
		for(int i = 1;i < m;i ++) {
			L += arr[i];
			int R = sum - L;
			ans = Math.min(ans, Math.abs(R-L));
		}
		System.out.println(ans);
	}
}

 

 九、问题描述 

一个平面向量表示从一个坐标点到另一个坐标点的变化量,一般用两个数 (x, y) 来表示。
两个向量相加是指分别将对应的两个数相加,例如 (x_1, y_1) 与 (x_2, y_2) 相加后得 (x_1+x_2, y_1+y_2)。
如果两个向量相加后,得到的向量两个值相等,我们称这两个向量为和谐向量对。例如 (3, 5) 和 (4, 2) 是和谐向量对。
给定 n 个向量,问能找到多少个和谐向量对?
输入格式:
  输入的第一行包含一个整数 n,表示向量的个数。
  接下来 n 行,每行两个整数 x_i, y_i,表示一个向量。
输出格式:
  输出一行,包含一个整数,表示有多少个和谐向量对。
  请注意,自己和自己不能成为一个和谐向量对。
样例输入:
5
9 10
1 3
5 5
5 4
8 6
样例输出:
2
样例输入:
4
1 1
2 2
1 1
2 2
样例输出:
6
样例说明:
  每两个向量组成一个和谐向量对。
评测用例规模与约定:
  对于 70% 的评测用例,1 <= n <= 1000;
  对于所有评测用例,1 <= n <= 100000,-1000000 <= x_i, y_i <= 1000000。
  请注意答案可能很大,可能需要使用 long long 来保存。
 

注意:该解法只能拿部分分数!
import java.util.*;
public class Main{
	static int[][]arr = new int [100005][2];
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for(int i = 1;i <= n;i ++) {
			arr[i][0] = sc.nextInt();
			arr[i][1] = sc.nextInt();
		}
		long ans = 0L;
		for(int i = 1;i <= n;i ++) {
			for(int j = i+1;j <= n;j ++) {
				if(arr[i][0]+arr[j][0] == arr[i][1]+arr[j][1]) {
					ans ++;
				}
			}
		}
		System.out.println(ans);
	}
}

十、问题描述 

给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。
三个水杯都没有标刻度线,在水杯之间可以相互倒水。当从一个杯子向另一个杯子倒水时,只能将一个杯子的水倒空或者将另一个杯子的水倒满。不允许倒到三个杯子以外的地方。
给定一个目标状态,请写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入格式:
  输入的第一行包含一个整数 n,表示总共有 n 组测试数据。
  接下来每组测试数据包含两行,第一行包含三个整数 V_1,V_2,V_3,分别表示三个水杯的体积。
  每组数据的第二行包含三个整数E_1,E_2,E_3(体积小于等于相应水杯体积)表示最终状态。
输出格式:
  输出 n 行,每行对应一组数据的结果。
  如果可以达到最终状态,输出最少的倒水次数,如果不能达到目标准备,输出-1。
样例输入:
2
6 3 1
4 1 1
9 3 2
7 1 1
样例输出:
3
-1
评测用例规模与约定:
  对于所有评测用例,0<n<=50,0<V_3<V_2<V_1<=100,0<=E_1<=V_1,0<=E_2<=V_2,0<=E_3<=V_3,E_1+E_2+E_3=V_1。
 

经典BFS,代码量大,但其实大部分是重复代码
import java.util.*;
public class Main{
	static class node{
		int a,b,c,step;
		public node(int a,int b,int c,int step) {
			this.a = a;
			this.b = b;
			this.c = c;
			this.step = step;
		}
	}
	static boolean [][][]vis = new boolean[105][105][105];
	static LinkedList<node>list = new LinkedList<>();
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for(int i = 0;i < n;i ++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			int x = sc.nextInt();
			int y = sc.nextInt();
			int z = sc.nextInt();
			bfs(a,b,c,x,y,z);
		}
	}
	static void bfs(int a,int b,int c,int x,int y,int z) {
		for(int i = 0;i <= 100;i ++) {
			for(int j = 0;j <= 100;j ++) {
				for(int k = 0;k <= 100;k ++) {
					vis[i][j][k] = false;
				}
			}
		}
		while(!list.isEmpty()) {
			list.pollFirst();
		}
		list.add(new node(a,0,0,0));
		vis[a][0][0] = true;
		while(!list.isEmpty()) {
			node cur = list.pollFirst();
			if(cur.a == x && cur.b == y && cur.c == z) {
				System.out.println(cur.step);
				return;
			}
			//a倒向b,c
			if(cur.a > 0) {
				if(cur.b < b) {
					if(cur.a >= b - cur.b && !vis[cur.a-(b-cur.b)][b][cur.c]) {
						list.add(new node(cur.a-(b-cur.b),b,cur.c,cur.step+1));
						vis[cur.a-(b-cur.b)][b][cur.c] = true;
					}else {
						if(!vis[0][cur.b + cur.a][cur.c]) {
							list.add(new node(0,cur.b + cur.a,cur.c,cur.step+1));
							vis[0][cur.b + cur.a][cur.c] = true;
						}
						
					}
				}
				if(cur.c < c) {
					if(cur.a >= c - cur.c && !vis[cur.a-(c-cur.c)][cur.b][c]) {
						list.add(new node(cur.a-(c-cur.c),cur.b,c,cur.step+1));
						vis[cur.a-(c-cur.c)][cur.b][c] = true;
					}else {
						if(!vis[0][cur.b][cur.c+cur.a]) {
							list.add(new node(0,cur.b,cur.c+cur.a,cur.step+1));
							vis[0][cur.b][cur.c+cur.a] = true;
						}
					}
				}
			}
			//b倒向a,c
			if(cur.b > 0) {
				if(cur.a < a) {
					if(cur.b >= a - cur.a && !vis[a][cur.b - (a - cur.a)][cur.c]) {
						list.add(new node(a,cur.b - (a - cur.a),cur.c,cur.step+1));
						vis[a][cur.b - (a - cur.a)][cur.c] = true;
					}else {
						if(!vis[cur.a+cur.b][0][cur.c]) {
							list.add(new node(cur.a+cur.b,0,cur.c,cur.step+1));
							vis[cur.a+cur.b][0][cur.c] = true;
						}
						
					}
				}
				if(cur.c < c) {
					if(cur.b >= c - cur.c && !vis[cur.a][cur.b - (c - cur.c)][c]) {
						list.add(new node(cur.a,cur.b - (c - cur.c),c,cur.step+1));
						vis[cur.a][cur.b - (c - cur.c)][c] = true;
					}else {
						if(!vis[cur.a][0][cur.c+cur.b]) {
							list.add(new node(cur.a,0,cur.c+cur.b,cur.step+1));
							vis[cur.a][0][cur.c+cur.b] = true;
							
						}
						
					}
				}
			}
			//c倒向a,b
			if(cur.c > 0) {
				if(cur.a < a) {
					if(cur.c >= a - cur.a && !vis[a][cur.b][cur.c - (a - cur.a)]) {
						list.add(new node(a,cur.b,cur.c - (a - cur.a),cur.step+1));
						vis[a][cur.b][cur.c - (a - cur.a)] = true;
					}else {
						if(!vis[cur.a+cur.c][cur.b][0]) {
							list.add(new node(cur.a+cur.c,cur.b,0,cur.step+1));
						}
					}
				}
				if(cur.b < b) {
					if(cur.c >= b - cur.b && !vis[cur.a][b][cur.c - (b - cur.b)]) {
						list.add(new node(cur.a,b,cur.c - (b - cur.b),cur.step+1));
						vis[cur.a][b][cur.c - (b - cur.b)] = true;
					}else {
						if(!vis[cur.a][cur.b+cur.c][0]) {
							list.add(new node(cur.a,cur.b+cur.c,0,cur.step+1));
							vis[cur.a][cur.b+cur.c][0] = true;
						}
						
					}
				}
			}
		}
		System.out.println("-1");
		return;
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值