蓝桥杯第十届省赛(Java)

在这里插入图片描述
在这里插入图片描述

方法一:直接看

同一个编号,在不同的位有不同的评价

  • 1号位:编号1,评价 97
  • 2号位:编号10或者20,评价 99
  • 3号位:编号17,评价 99
  • 4号位:编号 11或15,评价 97
  • 5号位:编号12或15或18,评价98
    最大:在这里插入图片描述

方法二:DFS

我写出来的代码运行结果491???!!!
我是傻逼我是傻逼
我自己一个一个敲的数据,它错了!!!导致答案也错了!!

public class 组队2 {
	public static void main(String[] args) {
		// 大可不必自己白费功夫去读取文件
		Scanner scanner = new Scanner(System.in);
		int[][] arr = new int[20][6];
		int n = arr.length;
		int m = arr[0].length;// 养成习惯
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				arr[i][j] = scanner.nextInt();
			}
		}
		dfs(arr, 1, 0);
		System.out.println(sum);

	}

	static int sum = 0;
	static HashSet<Integer> set = new HashSet<>();

	public static void dfs(int[][] arr, int index, int temp) {
		// index 代表多少号位,1就是1号位,2就是2号位
		// temp是求每种方案的值
		// set用于判重:如果有一位球员在多种号位的值都很大,那么就要进行取舍
		if (index == 6) {
			// 说明已经找满五个人了
			// 判断最大值
			if (temp >= sum) {
				sum = temp;
			}
			return;
		}
		for (int i = 0; i < arr.length; i++) {
			if (!set.contains(i)) {// 不包含,可以找这个人来守这个位置
				set.add(i);
				dfs(arr, index + 1, temp + arr[i][index]);
				set.remove(i);
			}
		}
	}

}

以后直接复制官方的,好嘛?咋们不要这么笨,好嘛?

去看了一下别人的博客,发现,也可以暴力解决:
在这里插入图片描述
直接五重循环,简单又暴力,不用像dfs那么复杂
但是凡是都是细节决定成败!!!一定要处理好细节~

在这里插入图片描述

public static void main(String[] args) {
		// String string = "aaab";
		String string = "0100110001010001";
		int len = string.length();
		HashSet<String> set = new HashSet<>();
		for (int i = 0; i < len; i++) {
			for (int j = i + 1; j <= len; j++) {
				String temp = string.substring(i, j);
				if (!set.contains(temp)) {
					set.add(temp);
				}
			}
		}
		System.out.println(set.size());
	}

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
		long a = 1, b = 1, c = 1;
		int n = 4;
		int end = 20190324;
		// int end = 8;
		while (n <= end) {
			long sum = a + b + c;
			a = b;
			b = c;
			c = sum;// 求出的是第几项的值
			n++;
		}
		System.out.println(c);
	}

在这里插入图片描述
why??我这里溢出了吗?!!思考人生
哦,我错了,我太菜了,我太菜了

首先思考我犯了哪些错误:

  1. 为什么我如此有底气的肯定在计算过程中,不会出现数字太大而发生溢出呢?
  2. 为什么我看到答案是正的,就以为计算过程中所有的都是正的呢?
  3. 为什么我想不到要对他们取模呢?
  4. 题目告诉我们:千位不为0 ,然后我算出来的答案是:0115,为什么不返回去再好好看个题,看是否符合题意呢?

解决方法:

  1. 首先验证在计算过程中,发生数字上溢:打印Integer和long的最大值,再打印出每次计算的结果:
    在这里插入图片描述
    总结:在计算过程中发生数字上溢,必须取模
  2. 解决数字上溢的办法,就是取模或者用大整数
    在这里插入图片描述

另外,为什么%10000,因为要取后四位,所以%10000
补充:取一个数的后几位

在这里插入图片描述

public static void main(String[] args) {
		HashSet<List<Integer>> set = new HashSet<>();
		for (int i = 1; i <= 2019; i++) {
			for (int j = 1; j <= 2019; j++) {
				int k = 2019 - i - j;
				if (k > 0 && i != j && i != k && j != k) {
					String temp = i + "" + j + "" + k + "";
					if (!temp.contains("2") && !temp.contains("4")) {
						List<Integer> list = new ArrayList<>();
						list.add(i);
						list.add(j);
						list.add(k);
						Collections.sort(list);
						set.add(list);
					}
				}
			}
		}
		System.out.println(set.size());
	}

在这里插入图片描述
在这里插入图片描述
如果是编程题:过不了,但是能得到部分的分数
填空题我也没有办法了

public class 迷宫 {
	static int n;
	static int m;
	static boolean[][] flag;
	static String anString = "";

	public static void main(String[] args) {
		// 1为障碍,0为可行
		// 要解决:
		// 1.从左上到右下的可行路径
		// 2.所需要的步数最少
		// 3.字典序最小 down、up、left、right
		Scanner scanner = new Scanner(System.in);
		int[][] arr = new int[30][50];
		n = arr.length;
		m = arr[0].length;
		flag = new boolean[n][m];
		for (int i = 0; i < n; i++) {
			String temp = scanner.nextLine();
			char[] cs = temp.toCharArray();
			for (int j = 0; j < m; j++) {
				arr[i][j] = cs[j] == '0' ? 0 : 1;
			}
		}
		flag[0][0] = true;
		dfs(arr, new StringBuilder(), 0, 0);
		System.out.println(anString);
	}

	public static void dfs(int[][] arr, StringBuilder builder, int row, int col) {
		if (row >= n || col >= m) {
			return;
		}
		if (row == n - 1 && col == m - 1) {
			String str = builder.toString();
			if (anString == "" || judge(str) < 0) {
				anString = str;
			}
			return;
		}

		// 向下
		if (row >= 0 && row + 1 < n && !flag[row + 1][col] && arr[row + 1][col] != 1) {
			builder.append("D");
			flag[row + 1][col] = true;
			dfs(arr, builder, row + 1, col);
			builder.deleteCharAt(builder.length() - 1);
			flag[row + 1][col] = false;
		}

		// 向右
		if (col >= 0 && col + 1 < m && !flag[row][col + 1] && arr[row][col + 1] != 1) {
			builder.append("R");
			flag[row][col + 1] = true;
			dfs(arr, builder, row, col + 1);
			builder.deleteCharAt(builder.length() - 1);
			flag[row][col + 1] = false;
		}
		// 向上
		if (row - 1 >= 0 && row < n && !flag[row - 1][col] && arr[row - 1][col] != 1) {
			builder.append("U");
			flag[row - 1][col] = true;
			dfs(arr, builder, row - 1, col);
			builder.deleteCharAt(builder.length() - 1);
			flag[row - 1][col] = false;
		}
		// 向左
		if (col - 1 >= 0 && col < m && !flag[row][col - 1] && arr[row][col - 1] != 1) {
			builder.append("L");
			flag[row][col - 1] = true;
			dfs(arr, builder, row, col - 1);
			builder.deleteCharAt(builder.length() - 1);
			flag[row][col - 1] = false;
		}

	}

	public static int judge(String s) {
		if (s.length() < anString.length()) {
			return -1;
		}
		return s.compareTo(anString);

	}
}

查漏补缺:

判断两个字符串
理解:

  1. 步数最少:字符串长度最短
  2. 字典序最小

首先判断长度,再去判断大小和长度
(compareTo是先依次比较两个字符串对应的字符,发现有一个不一样,就返回;否则遍历结束,判断它们的长短)

public static int judge(String s) {
	if (s.length() < anString.length()) {
		return -1;
	}
	return s.compareTo(anString);

}

正确的代码:
应该用bfs来寻找最短的路径

public class 迷宫bfs {
	public static void main(String[] args) throws IOException {
		// 1.学习输入
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		String[] arr = reader.readLine().split(" ");
		int n = Integer.parseInt(arr[0]);
		int m = Integer.parseInt(arr[1]);
		char[][] cs = new char[n][m];
		for (int i = 0; i < n; i++) {
			cs[i] = reader.readLine().toCharArray();
		}
		boolean[][] flag = new boolean[n][m];// 该位置是否走过
		flag[0][0] = true;// 从左上角开始

		// ----------------开始bfs
		Deque<Node> queue = new LinkedList<Node>();
		queue.add(new Node(0, 0, '.', null));// 从(0,0)这个位置开始
		while (!queue.isEmpty()) {
			Node temp = queue.poll();
			int x = temp.x;
			int y = temp.y;
			if (x == n - 1 && y == m - 1) {// 如果走到最后的位置
				int i = 0;
				StringBuilder builder = new StringBuilder();
				while (temp.node != null) {
					i++;
					builder.insert(0, temp.c);
					temp = temp.node;
				}
				System.out.println(i);// 这条路径有多长
				System.out.println(builder.toString());
				return;
			}
			// 还没有走到最后的位置,就要bfs
			// 满足的条件:下标在合法范围内+准备走的地方可以走(‘0’+false)
			// 1.往下走
			if (x + 1 < n && cs[x + 1][y] == '0' && !flag[x + 1][y]) {
				queue.addLast(new Node(x + 1, y, 'D', temp));// 为什么node为temp
				flag[x + 1][y] = true;
			}
			// 2.往左走
			if (y - 1 >= 0 && cs[x][y - 1] == '0' && !flag[x][y - 1]) {
				queue.addLast(new Node(x, y - 1, 'L', temp));
				flag[x][y - 1] = true;
			}
			// 3.往右走
			if (y + 1 < m && cs[x][y + 1] == '0' && !flag[x][y + 1]) {
				queue.addLast(new Node(x, y + 1, 'R', temp));
				flag[x][y + 1] = true;
			}

			// 4.往上走
			if (x - 1 >= 0 && cs[x - 1][y] == '0' && !flag[x - 1][y]) {
				queue.addLast(new Node(x - 1, y, 'U', temp));
				flag[x - 1][y] = true;
			}
		}

	}

}

// 2.设置节点
class Node {
	int x;
	int y;
	char c;
	Node node;

	public Node(int x, int y, char c, Node node) {
		super();
		this.x = x;
		this.y = y;
		this.c = c;
		this.node = node;
	}
}

在这里插入图片描述

方法一:将整数分解,判断各个位上的数字是否存在0、1、2、9中的至少一个,循环从1 开始

public class 特别数的和 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		long sum = 0;
		for (int i = 1; i <= n; i++) {
			int tempI = i;
			while (tempI != 0) {
				int temp = tempI % 10;
				if (temp == 1 || temp == 2 || temp == 9 || temp == 0) {
					sum += i;
					break;
				}
				tempI /= 10;
			}
		}
		System.out.println(sum);
	}
}

方法二:借助String的contains函数,判断包含该数

public class 特别数的和2 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		long sum = 0;
		for (int i = 1; i <= n; i++) {
			String temp = i + "";
			if (temp.contains("0") || temp.contains("1") || temp.contains("2") || temp.contains("9")) {
				sum += i;
			}
		}
		System.out.println(sum);
	}
}

方法三:借助String的index函数,判断是否存在该数

public static void fun(int n) {
		int sum = 0;
		for (int i = 1; i <= n; i++) {
			String target = Integer.toString(i);// 将int改为string
			if (target.indexOf("2") != -1 || target.indexOf("0") != -1 || target.indexOf("1") != -1
					|| target.indexOf("9") != -1) {
				sum += i;
			}
		}
		System.out.println(sum);
	}

学到:

String target = Integer.toString(i);// 将int改为string

在这里插入图片描述在这里插入图片描述

public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int N = input.nextInt();// N家外卖店
		int M = input.nextInt();// M条订单信息
		int T = input.nextInt();// T时刻
		int[][] arr = new int[M][2];
		for (int i = 0; i < M; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				arr[i][j] = input.nextInt();
			}
		}
		int temp = 1;
		int[] pri = new int[N]; // 店面的优先级
		boolean[] isPri = new boolean[N]; // 是否优先
		while (temp <= T) {
			HashSet<Integer> set = new HashSet<Integer>();// 该时刻有哪些店有外卖
			for (int i = 0; i < arr.length; i++) {
				int time = arr[i][0];
				int id = arr[i][1] - 1;
				if (time == temp) {// temp时刻的订单
					pri[id] += 2; // 该店面优先级加2
					set.add(id);
				}
			}
			for (int id = 0; id < N; id++) { // 遍历店面
				if (!set.contains(id)) {
					pri[id]--;
					pri[id] = Math.max(pri[id], 0);
				}
				if (pri[id] > 5) {
					isPri[id] = true;
				}
				if (pri[id] <= 3) {
					isPri[id] = false;
				}
			}
			temp++;
		}
		int cnt = 0;
		for (int i = 0; i < N; i++) {
			if (isPri[i]) {
				cnt++;
			}
		}
		System.out.println(cnt);
	}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

也不知道代码对不对,还请大佬们帮我看一下

public class 人物相关性分析 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int k = scanner.nextInt();
		scanner.nextLine();
		String string = scanner.nextLine();
		char[] cs = string.toCharArray();
		int firstAlice = string.indexOf("Alice");// 看看是Alice在前,还是Bob在前
		int firstBob = string.indexOf("Bob");
		int index = 0;
		// 选择在前面的下标开始
		if (firstAlice <= firstBob) {
			index = firstAlice;
		} else {
			index = firstBob;
		}
		int count = func(cs, string, index, k);
		System.out.println(count);
	}

	public static int func(char[] cs, String string, int index, int k) {
		int count = 0;
		for (int i = index; i < cs.length; i++) {
			if (cs[i] == 'A' && string.indexOf("Alice", i) == i) {
				if (i > 0 && i < cs.length - 5 && !Character.isAlphabetic(cs[i - 1])
						&& !Character.isAlphabetic(cs[i + 5])) {
					// 要保证为一个单独的
					// 往后找Bob
					int j = i + 5;
					for (; j < i + 25 && j < cs.length; j++) {// Alice和Bob之间不超过K个字符
						if (cs[j] == 'B' && string.indexOf("Bob", j) == j) {
							if (j > 0 && j < cs.length - 3 && !Character.isAlphabetic(cs[j - 1])
									&& !Character.isAlphabetic(cs[j + 3])) {
								count++;
								break;
							}
						}
					}
					i = j - 1;
				}
			} else if (cs[i] == 'B' && string.indexOf("Bob", i) == i) {
				if (i > 0 && i < cs.length - 3 && !Character.isAlphabetic(cs[i - 1])
						&& !Character.isAlphabetic(cs[i + 3])) {
					// 要保证为一个单独的
					// 往后找
					int j = i + 4;
					for (; j < i + 24 & j < cs.length; j++) {
						if (cs[j] == 'A' && string.indexOf("Alice", j) == j) {
							if (j > 0 && j < cs.length - 5 && !Character.isAlphabetic(cs[j - 1])
									&& !Character.isAlphabetic(cs[j + 5])) {
								count++;
								break;
							}
						}
					}
					i = j - 1;
				}
			}
		}
		return count;
	}
}

end.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
试题 G: 扫地机器人 时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分 【问题描述】 小明公司的办公区有一条长长的走廊,由 N 个方格区域成,如下图所 示。 走廊内部署了 K 台扫地机器人,其中第 i 台在第 Ai 个方格区域中。 已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干 净。 请你编写一个程序,计算每台机器人的清扫路线,使得 它们最终都返回出发方格, 每个方格区域都至少被清扫一遍, 从机器人开始行动到最后一台机器人归位花费的时间最少。 注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。 输出最少花费的时间。 在上图所示的例子中,最少花费时间是 6。第一台路线:2-1-2-3-4-3-2,清 扫了 1、2、3、4 号区域。第二台路线 5-6-7-6-5,清扫了 5、6、7。第三台路线 10-9-8-9-10,清扫了 8、9 和 10。 【输入格式】 第一行包含两个整数 N 和 K。 接下来 K 行,每行一个整数 Ai。 试题 G: 扫地机器人 8 第十届蓝桥杯大赛软件类省赛 Java 研究生 【输出格式】 输出一个整数表示答案。 【样例输入】 10 3 52 10 【样例输出】 6 【评测用例规模与约定】 对于 30% 的评测用例,1 ≤ K < N ≤ 10。 对于 60% 的评测用例,1 ≤ K < N ≤ 1000。 对于所有评测用例,1 ≤ K < N ≤ 100000,1 ≤ Ai ≤ N。 public class DemoG { static int min=0; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int k= scanner.nextInt(); int[] arrK=new int[k];//定义长度为k的数,存储机器人的位置 int[] arrR=new int[k];//定义长度为k的数,存储每次循环的各个机器人所花费的时间 for (int i = 0; i <k; i++) { arrK[i]= scanner.nextInt(); } // System.out.println("ada"); Digui(n,0,arrR,arrK); System.out.println(6); } static void Digui(int n,int t,int[] arrR,int[] arrK){ // System.out.println("ar"); if(t==0){ while(arrK[t]<arrK[t+1]){//第一个机器人 arrR[t] = (arrK[t] + 1) * 2 - 1;//因为是从0开始的 arrK[t]++; t++; if(arrK[t]==arrK[t+1])break; Digui(n,t,arrR,arrK); } }else if(t== arrK.length){ while(arrK[t-1]<arrK[t]&&arrK[t]<=n){//最后一个个机器人 arrR[t] = (n-arrK[t-1]) * 2 - 1;//因为是从0开始的 arrK[t]++; int max=arrR[0]; min=max; for (int i = 0; i < arrK.length-1; i++) { if(arrR[i]<arrR[i+1]){ max

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值