CCF 模拟题 202006-1 线性分类器 Java 100分

  • Post author:
  • Post category:java


CCF练习 202006-1 线性分类器 输出规范很重要



题目心得

这道题理解起来很简单,思路也比较清晰。简单说一下本人的解题思路:

1. 首先,我们在读入数据的时候,可以对于类型A和B进行处理,为其赋值,这样就可以将其转换为int类型

2. 其次,对于类型A和类型B的区别可以转换成将参数和点坐标代入等式左端时,得到的结果和零的大小比较。

3. 接着,我们需要自己定义一下判定正确的规则,将规则转换为代码语言。思路:

判定正确,即,判定结果该点为A类型,实际上该点也是A类型,或者,判定结果该点为B类型,实际上该点也是B类型。

那么此时,按照2中的思路,出现一个不确定的情况:代入的结果大于零的时候为A类型,还是小于零的时候为A类型呢?

这个时候我们就需要找一个基准,来明确这个问题。在这道题中,可以假设每条直线对于第一个点的判断都是正确的:比如,当我们将三个参数和第一个点的坐标(x,y)代入等式左端时,得到的结果大于零且第一个点的类型为A,则我们认为对于每一次判断,如果结果大于零,那么该点的判断结果就为A类型;如果结果小于零,那么该点的判定结果为B类型。

4. 最后,将判定结果和实际点的类型进行比较。遍历数组中的点,与参数一起代入公式进行判断。如果出现某个点的类型判断错误,则该条直线不能将两种类型的点进行完美地分隔,就可以输出“No”然后跳出循环,以节省时间。如果对于数组中所有的点都判断正确,则输出“Yes”。对于直线判断结果,可以使用Boolean类型表示。

最后的最后,唠叨一下,注意输出的格式:“Yes”和“No”,一定要看清大小写!!

做完题不要着急提交,请务必检查输出!!

如果怎么分析代码都没有bug,思维严谨,却还是通过不了,请务必检查输出!!



完整代码

由于本人学术不精,粘出代码仅供大家参考,欢迎大家参与讨论和批评指正。

import java.util.Scanner;
public class Main {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//点的个数
		int m = sc.nextInt();//查询的个数
		//点的坐标和点的类型:按照题目描述只有两种类型
		int[][] p = new int[n][3];
		//读入点的信息
		for(int i=0;i<n;i++){
			p[i][0] = sc.nextInt();
			p[i][1] = sc.nextInt();
			String c = sc.next();
			if(c.equals("A")){
				p[i][2] = 0;
			}else{
				p[i][2] = 1;
			}
		}
		
		//读入直线的信息
		//我们假设第一个点的分类是正确的:
		//也就是如果第一个点的res值大于零,且该点的类型为A,那我们就认为大于零的所有点都是A类
		//相反,如果第一个点的res小于零,就认为所有res小于零的点是A类
		//那么只存在上述两种情况:大于0的类是A和小于0的类是A
		//我们把这两种情况设置成int类型的值,命名为sit
		//第一种情况:sit=0;(大于0的类是A
		//第二种情况:sit=1;(小于0的类是A
		int sit = -1;//初始值设为-1
		int type = p[0][2];//记录第一个点的实际类别,type==1: A; type==2: B
		Boolean judge = true;//记录判断的是否正确
		for(int i=0;i<m;i++){
			int t1 = sc.nextInt();
			int t2 = sc.nextInt();
			int t3 = sc.nextInt();
			//遍历point信息数组,计算出类别;等式左边的数res大于零为一类,小于零为另一类
			//因为不存在落在直线上的点,所以没有等于零的情况
			int rf = t1 + p[0][0]*t2 + p[0][1]*t3;//记录每一次查询对于第一个点的类别判定的结果
			//第一个点的判断结果如果大于零且实际结果是A的情况,等同于结果小于零且实际结果是B
			if((rf>0 && type==0)||(rf<0 && type==1) ){
				sit = 0;
			}else{
				sit = 1;
			}
			
			//开始对除了第一个点的每个点进行查询
			for(int j=1;j<n;j++){
				int res  = t1 + p[j][0]*t2 + p[j][1]*t3;
				//判定正确的规则:
				//判定的结果与实际的结果相等
				//如果是sit=0的情况,如果res大于0,则点的类型应该是a,也就是p[j][2]==0,或者res<0,p[j][2]==1
				if(sit==0 &&((res>0 && p[j][2]==0)||(res<0 && p[j][2]==1))){
					judge = true;
				}else if(sit==1 && ((res>0 && p[j][2]==1)||(res<0 && p[j][2]==0))){
					judge = true;
				}else{
					judge = false;
					break;
				}
			}
			if(judge){
				System.out.println("Yes");
			}else{
				System.out.println("No");
			}
		}
		
		//关闭流
		sc.close();
	}
}

提交结果:

在这里插入图片描述



版权声明:本文为qq_44654127原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。