csp认证-Java-线性分类器,稀疏向量,报数,回收站选址,小中大,二十四点,小明放学,消息传递接口,卖菜

线性分类器

100分代码:

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt(), m = scanner.nextInt();
		double[][] dots = new double[n][3], lines = new double[m][3];
		boolean[] result = new boolean[m];
		for (int i = 0; i < n; i++) {
			dots[i][0] = scanner.nextInt();
			dots[i][1] = scanner.nextInt();
			dots[i][2] = (int) scanner.next().toCharArray()[0];
		}
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < 3; j++) {
				lines[i][j] = scanner.nextInt();
			}
		}
		boolean res;
		for (int i = 0; i < m; i++) {
			res = true;
			Set<Double> one = new HashSet<Double>();
			Set<Double> two = new HashSet<Double>();
			if (lines[i][2] == 0) {
				for (int j = 0; j < n; j++) {
					double num = -lines[i][0] / lines[i][1];
					if (num > dots[j][0]) {
						if (one.isEmpty()) {
							one.add(dots[j][2]);
						} else {
							if (!one.contains(dots[j][2])) {
								res = false;
								break;
							}
						}
					} else {
						if (two.isEmpty()) {
							two.add(dots[j][2]);
						} else {
							if (!two.contains(dots[j][2])) {
								res = false;
								break;
							}
						}
					}
				}
			} else {
				for (int j = 0; j < n; j++) {
					double num = (-(lines[i][1] * dots[j][0]) - lines[i][0]) / lines[i][2];
					if (num > dots[j][1]) {
						if (one.isEmpty()) {
							one.add(dots[j][2]);
						} else {
							if (!one.contains(dots[j][2])) {
								res = false;
								break;
							}
						}
					} else {
						if (two.isEmpty()) {
							two.add(dots[j][2]);
						} else {
							if (!two.contains(dots[j][2])) {
								res = false;
								break;
							}
						}
					}
				}
			}
			result[i] = res;
		}
		for (boolean b : result) {
			if (b) {
				System.out.println("Yes");
			} else {
				System.out.println("No");
			}
		}
		scanner.close();
	}
}

在这里插入图片描述

  1. 55分踩坑:漏掉了 “y = 0” 的情况。以后要先看清看懂题目,然后再根据题目最后的测试点设计测试用例,在所有的用例都无误才考虑提交。
  2. 70分踩坑:存直线系数的数组用了int类型数组,在使用除法时结果为整数(实际上结果应该为浮点数),所以应该考虑好数的类型再写代码。

    原来可以直接判断 a + bx + cy 大于还是小于0,如果 a + bx + cy < 0,则该点位于直线上方;如果 a + bx + cy > 0,则该点位于直线下方。

稀疏向量

60分代码:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt(), a = scanner.nextInt(), b = scanner.nextInt(),result = 0;
		int[][] u = new int[a][2], v = new int[b][2];
		Map<Integer, Integer> one = new HashMap<Integer, Integer>();
		for (int i = 0; i < a; i++) {
			u[i][0] = scanner.nextInt();
			u[i][1] = scanner.nextInt();
			one.put(u[i][0], u[i][1]);
		}
		for (int i = 0; i < b; i++) {
			v[i][0] = scanner.nextInt();
			v[i][1] = scanner.nextInt();
			result += one.getOrDefault(v[i][0], 0) * v[i][1];
		}
		System.out.println(result);
		scanner.close();
	}
}

在这里插入图片描述
    尝试过不用Map而用数组,依然运行超时,而且运行错误,估计是内存用的太多了。上网查了一下,原来Scanner的速度很慢,所以我改用了BufferedReader,然后通过了。使用BufferedReader进行读取效率会大大的提高。

使用Java语言刷OJ经常超时的解决办法

100分代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {// 读取下一个字符串
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static String nextLine() throws IOException {// 读取下一行字符串
		return reader.readLine();
	}

	static int nextInt() throws IOException {// 读取下一个int型数值
		return Integer.parseInt(next());
	}

	static long nextLong() throws IOException {// 读取下一个long型数值
		return Long.parseLong(next());
	}

	static double nextDouble() throws IOException {// 读取下一个double型数值
		return Double.parseDouble(next());
	}
}

public class Main {
	public static void main(String[] args) {
		try {
			int n = Reader.nextInt(), a = Reader.nextInt(), b = Reader.nextInt();
			long result = 0;
			int[][] u = new int[a][2];
			Map<Integer, Integer> one = new HashMap<Integer, Integer>();
			for (int i = 0; i < a; i++) {
				u[i][0] = Reader.nextInt();
				u[i][1] = Reader.nextInt();
				one.put(u[i][0], u[i][1]);
			}
			int index, value;
			for (int i = 0; i < b; i++) {
				index = Reader.nextInt();
				value = Reader.nextInt();
				if (one.containsKey(index)) {
					result += one.get(index) * value;
				}
			}
			System.out.println(result);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

报数

100分代码:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int rounds = scanner.nextInt(),total = 0;
		int[] array = new int[4];
		for (int index = 0, i = 0; i < rounds;) {
			total++;
			if (String.valueOf(total).contains("7") || total % 7 == 0) {
				array[index]++;
			} else {
				i++;
			}
			index = (++index) % 4;
		}
		for (int i : array) {
			System.out.println(i);
		}
	}
}

回收站选址

100分代码:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt(), x, y;
		int[] result = new int[5];
		Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
		for (int i = 0; i < n; i++) {
			x = scanner.nextInt();
			y = scanner.nextInt();
			if (map.containsKey(x)) {
				map.get(x).add(y);
			} else {
				Set<Integer> set = new HashSet<Integer>();
				set.add(y);
				map.put(x, set);
			}
		}
		boolean up, down, left, right;
		for (int a : map.keySet()) {
			Set<Integer> setL = map.get(a - 1);
			Set<Integer> setM = map.get(a);
			Set<Integer> setR = map.get(a + 1);
			if (setL == null || setR == null) {
				continue;
			} else {
				for (int b : setM) {
					if (setL.contains(b) && setR.contains(b)) {
						left = true;
						right = true;
					} else {
						continue;
					}
					if (setM.contains(b + 1)) {
						up = true;
					} else {
						continue;
					}
					if (setM.contains(b - 1)) {
						down = true;
					} else {
						continue;
					}
					if (up && down && left && right) {
						up = false;
						down = false;
						left = false;
						right = false;
						int index = 0;
						if (setL.contains(b + 1)) {
							index++;
						}
						if (setR.contains(b + 1)) {
							index++;
						}
						if (setL.contains(b - 1)) {
							index++;
						}
						if (setR.contains(b - 1)) {
							index++;
						}
						result[index]++;
					}
				}
			}
		}
		for (int i : result) {
			System.out.println(i);
		}
	}
}

小中大

100分代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

public class Main {
	public static void main(String[] args) {
		try {
			int n = Reader.nextInt(), max = 0, min = 0, mid = 0;
			int[] array = new int[n];
			for (int i = 0; i < n; i++) {
				array[i] = Reader.nextInt();
			}
			if (array[0] > array[n - 1]) {
				max = array[0];
				min = array[n - 1];
			} else {
				max = array[n - 1];
				min = array[0];
			}
			if (n % 2 == 0) {
				mid = (array[n / 2] + array[n / 2 - 1]) / 2;
				if ((array[n / 2] + array[n / 2 - 1]) % 2 != 0) {
					System.out.println(max + " " + mid + ".5 " + min);
				} else {
					System.out.println(max + " " + mid + " " + min);
				}				
			} else {
				mid = array[n / 2];
				System.out.println(max + " " + mid + " " + min);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

二十四点

    思路是:分两个栈,分别存储数字和运算符,遇到数字直接入栈,遇到“+”或“-”直接入栈,遇到“*”或“/”则弹数运算再将结果入栈。全部字符遍历一遍后,有多少个运算符则运算多少次。

100分代码:

import java.util.Deque;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

public class Main {
	public static void main(String[] args) {
		try {
			int n = Reader.nextInt();
			boolean[] result = new boolean[n];
			for (int i = 0; i < n; i++) {
				int temp = 0;
				char[] string = Reader.next().toCharArray();
				Deque<Integer> number = new LinkedList<Integer>();
				Deque<Character> operator = new LinkedList<Character>();
				for (int j = 0; j < string.length; j++) {
					if (string[j] >= '0' && string[j] <= '9') {
						number.add(string[j] - 48);
					} else if (string[j] == '+' || string[j] == '-') {
						operator.add(string[j]);
					} else {
						int left = number.pollLast();
						char op = string[j++];
						int right = string[j] - 48;
						if (op == 'x') {
							number.add(left * right);
						} else {
							number.add(left / right);
						}
					}
				}
				int size = operator.size();
				if (size==0) {
					temp=number.pollFirst();
				} else {
					for (int j = 0; j < size; j++) {
						if (j==0) {
							int left = number.pollFirst();
							char op = operator.pollFirst();
							int right = number.pollFirst();
							if (op == '+') {
								temp +=(left + right);
							} else {
								temp += (left - right);
							}
						} else {
							char op = operator.pollFirst();
							int right = number.pollFirst();
							if (op == '+') {
								temp += right;
							} else {
								temp -= right;
							}
						}
					}
				}
				if (temp == 24) {
					result[i] = true;
				}
			}
			for (boolean b : result) {
				System.out.println(b ? "Yes" : "No");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

小明放学

    这一题一开始用暴力法算出每一次小明所处的灯和等待时间,然后超时。
    看了网上的代码发现可以将这个题看成一个时间轴,0__(红)__30__(绿)__30__(黄)__3。

  1. 将每一个灯的剩余时间转换成在时间轴上的时间点,比如小明现在看到红灯且剩余5s,那么在时间轴上这个时间点就是25。
  2. 在这个时间点的基础上加上之前所有的耗时,就得到现在小明所处的灯。比如之前共耗时50s,那么现在小明所处的时间点是75。
  3. 由于灯是红绿黄不断循环,如果当前时间点超过红绿黄时间总和,就会来到新一轮的红绿黄,那么我们需要将这个总耗时和红绿黄总时间取余,获得当前在新的红绿黄时间轴的时间点12。
  4. 根据时间轴的划分我们可以知道当前所处的是红灯,而且红灯已经亮了12s,还需要等18s。(如果当前是黄灯则要加上红灯的时间)

100分代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

public class Main {

	public static void main(String[] args) {
		try {
			int r = Reader.nextInt(), y = Reader.nextInt(), g = Reader.nextInt();
			int[] light = new int[] { 0, r, r + g + y, g + r };
			int n = Reader.nextInt(), sum = r + g + y;
			long result = 0;
			for (int i = 0; i < n; i++) {
				int k = Reader.nextInt(), t = Reader.nextInt();
				if (k == 0) {
					result += t;
				} else {
				    // 获得在时间轴上的时间点
					int time = (light[k] - t + (int)(result % sum)) % sum;
					if (time < r) {// 红
						result += (r - time);// 时间点转剩余时间
					} else if (time < r + g) {// 绿
						continue;
					} else {// 黄
						result += (r + g + y - time + r);
					}
				}
			}
			System.out.println(result);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

消息传递接口

60分代码:估计是超时了

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

public class Main {

	private static boolean isValid(int currentProgram, boolean[] status, int[] index, ArrayList<String[]> list) {
		status[currentProgram] = true;// 当前进程已被访问过
		String cur = list.get(currentProgram)[index[currentProgram]];// 当前进程执行到哪个指令了
		int destProgram = cur.charAt(1) - 48;// 获取目的进程
		if (status[destProgram] || index[destProgram] == list.get(destProgram).length) {
			// 如果目的进程已经访问过 或者 目的进程已经执行完指令 则发生死锁
			status[currentProgram] = false;
			return false;
		}
		String dest = list.get(destProgram)[index[destProgram]];// 目的进程执行到哪个指令了
		boolean flag = true;// 是否正常
		if (dest.charAt(1) - 48 != currentProgram) {
			// 目的进程的目的进程不是当前进程,则继续检查
			flag = isValid(destProgram, status, index, list);
		} else {
			if (cur.charAt(0) == dest.charAt(0)) {// 同为R或S则发生死锁
				flag = false;
			} else {// 可以配对
				index[currentProgram]++;
				index[destProgram]++;
				flag = true;
			}
		}
		status[currentProgram] = false;// 恢复现场
		return flag;
	}

	public static void main(String[] args) {
		try {
			int T = Reader.nextInt(), n = Reader.nextInt();
			List<Integer> result = new ArrayList<Integer>(T);
			for (int i = 0; i < T; i++) {// T组数据
				ArrayList<String[]> list = new ArrayList<String[]>();// 存每个进程
				boolean[] status = new boolean[n];// 记录进程是否被访问过
				int[] index = new int[n];// 记录进程执行到哪个指令,相当于队列
				for (int j = 0; j < n; j++) {
					String[] split = Reader.nextLine().split(" ");// 分割指令
					list.add(split);
				}
				boolean dead = false;// 是否有死锁
				for (int j = 0; j < n; j++) {// 依次检测每个进程
					int length = list.get(j).length;
					boolean flag = false;
					while (index[j] < length) {// 当前进程还有没执行完的指令
						if (!isValid(j, status, index, list)) {
							// 判断当前指令是否产生死锁,如果过程中发现有配对的则进行配对
							flag = true;
							break;
						}
					}
					if (flag) {
						dead = true;
						break;
					}
				}
				if (dead) {
					result.add(1);
				} else {
					result.add(0);
				}
			}
			for (Integer integer : result) {
				System.out.println(integer);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

卖菜(2)

100分代码:用了BitSet,感觉开挂了😁😁😁

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.BitSet;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

public class Main {

	public static void main(String[] args) {
		try {
			int n = Reader.nextInt();
			BitSet one = new BitSet(1000001);
			BitSet two = new BitSet(1000001);
			for (int i = 0; i < n; i++) {
				one.set(Reader.nextInt(), Reader.nextInt(), true);
			}
			for (int i = 0; i < n; i++) {
				two.set(Reader.nextInt(), Reader.nextInt(), true);
			}
			one.and(two);
			System.out.println(one.cardinality());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值