问题描述:
解题思路
容易想到只要把点的坐标带入方程看结果与0的大小可以判断出点在直线左侧还是右侧。
对于每一个方程(直线),判断的过程如下:
记录下每个点的信息(包括哪一类),判断的时候先计算第一个点位于直线左边还是右边,然后看剩余的点是否和第一个点同类别:
如果同类别,那么该点应该和第一个点在直线同一边
如果不同类别,那么该点应该和第一个点分处于直线两侧
题解:
import java.util.Scanner;
public class 线性分类器 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] data = new int[n][2];
char[] type = new char[n];
for (int i = 0; i < n; i++) {
data[i][0] = sc.nextInt();
data[i][1] = sc.nextInt();
type[i] = sc.next().charAt(0);
}
boolean[] res = new boolean[m];
boolean up = true;//表示A在直线上方
int[][] line = new int[m][3];
for (int i = 0; i < m; i++) {
line[i][0] = sc.nextInt();
line[i][1] = sc.nextInt();
line[i][2] = sc.nextInt();
}
long points;
//判断第一个点哪种类型
points = line[0][0] + line[0][1] * data[0][0] + line[0][2] * data[0][1];
if (type[0] == 'A' && points > 0) {
up = true;
} else if (type[0] == 'B' && points < 0) {
up = true;
} else {
up = false;
}
for (int i = 0; i < m; i++) {
for (int j = 1; j < n; j++) {
points = line[i][0] + line[i][1] * data[j][0] + line[i][2] * data[j][1];
if (up) {
if (type[j] == 'A' && points > 0) {
res[i] = true;
} else if (type[j] == 'A' && points < 0) {
res[i] = false;
break;
} else if (type[j] == 'B' && points > 0) {
res[i] = false;
break;
} else if (type[j] == 'B' && points < 0) {
res[i] = true;
}
} else if (!up) {
if (type[j] == 'A' && points > 0) {
res[i] = false;
break;
} else if (type[j] == 'A' && points < 0) {
res[i] = true;
} else if (type[j] == 'B' && points > 0) {
res[i] = true;
} else if (type[j] == 'B' && points < 0) {
res[i] = false;
break;
}
}
}
}
for (int i = 0; i < m; i++) {
if (res[i] == true) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}