线性分类器
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();
}
}
- 55分踩坑:漏掉了 “y = 0” 的情况。以后要先看清看懂题目,然后再根据题目最后的测试点设计测试用例,在所有的用例都无误才考虑提交。
- 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进行读取效率会大大的提高。
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。
- 将每一个灯的剩余时间转换成在时间轴上的时间点,比如小明现在看到红灯且剩余5s,那么在时间轴上这个时间点就是25。
- 在这个时间点的基础上加上之前所有的耗时,就得到现在小明所处的灯。比如之前共耗时50s,那么现在小明所处的时间点是75。
- 由于灯是红绿黄不断循环,如果当前时间点超过红绿黄时间总和,就会来到新一轮的红绿黄,那么我们需要将这个总耗时和红绿黄总时间取余,获得当前在新的红绿黄时间轴的时间点12。
- 根据时间轴的划分我们可以知道当前所处的是红灯,而且红灯已经亮了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();
}
}
}