CSP202006-1 线性分类器 (Python)

文章目录

题目

试题编号: 202006-1
试题名称: 线性分类器
时间限制: 1.0s
内存限制: 512.0MB

题目描述
  考虑一个简单的二分类问题——将二维平面上的点分为 A 和 B 两类。
  训练数据包含 n 个点,其中第 i 个点(1 ≤ i ≤ n)可以表示为一个三元组(xi1,yi1 ,typei),即该点的横坐标、纵坐标和类别。
  在二维平面上,任意一条直线可以表示为θ01x+θ2y=0的形式,即由θ0、θ1和θ2三个参数确定该直线,且满足θ1和θ2不同时为 0。
  基于这 n 个已知类别的点,我们想要在平面上找到一条直线作为一个线性分类器。具体来说,这条线要把训练数据中的 A、B两类点完美分隔开来,即一侧只有 A 类点、另一侧只有B类点。这样,对于任意一个的未知类别的点,我们就可以根据它是位于直线的哪一侧来预测它的类别了。
  在本题中我们仅需要处理 m个如下查询∶给定一条直线,判断它是否能将训练数据中的 A、B 两类点完美分开。
输入格式
  从标准输入读入数据。
  输入共 n+m+1行。
  第一行包含用空格分隔的两个正整数 n 和 m ,分别表示点和查询的个数。
  第二行到第n+1行依次输入 n 个点的信息。第n+1行(1≤ i ≤ n)包含用空格分隔的三项xi、yi和typei,分别表示第 i 个点的横、纵坐标和类别,其中坐标为整数、类别为一个大写英文字母A或B。
  第n+2行到第n+m+1行依次输入 m个查询。第j+n+1行(1≤ j ≤ m)包含用空格分隔的三个整数θ0、θ1和θ2,表示第j个查询中给定直线的三个参数。
输出格式
  输出到标准输出。
  输出共 m 行,每行输出一个字符串。
  第 j 行(1≤ j ≤ m)输出的字符串对应第 j 个查询的结果∶ 如果给定直线可以完美分隔A、B两类点,则输出Yes; 否则输出No。
样例1输入
  9 3
  1 1 A
  1 0 A
  1 -1 A
  2 2 B
  2 3 B
  0 1 A
  3 1 B
  1 3 B
  2 0 A
  0 2 -3
  -3 0 2
  -3 1 1
样例1输出
  No
  No
  Yes
样例1 解释
  只有第 3个查询给出的直线能将A、B两类点完美分隔。
在这里插入图片描述

子任务
  输入数据保证不存在恰好落在给定直线上的点;
  0< n ≤103、0< m ≤20,且A、B两类点的数量均不为0;
  所有点的坐标和给定直线的三个参数均为整数,且绝对值≤106;
  任意两个点的坐标不完全相同。
在这里插入图片描述

程序代码

# 输入n,m
n,m = input().split()
n = int(n)
m = int(m)

# A\B类测试点列表
pointsA = []
pointsB = []

# 输入测试点格式转换并加入列表
for i in range(n):
    point = input().split()
    point[0] = int(point[0])
    point[1] = int(point[1])
    if point[2] == 'A':
        pointsA.append(point)
    else:
        pointsB.append(point)

# 直线参数列表
lines = []

# 输入直线参数格式转换并加入列表
for i in range(m):
    line = input().split()
    for j in range(3):
        line[j] = int(line[j])
    lines.append(line)

# 遍历直线参数列表 并统计在直线上方的A\B类点数目 判断并输出
for i in range(m):
    c,a,b = lines[i]
    sumA = 0
    sumB = 0

    # 统计在直线上方的A类点数目
    for j in range(len(pointsA)):
        x,y,tag = pointsA[j]
        value = a * x + b * y + c
        if value > 0:
            sumA += 1

    # 统计在直线上方的B类点数目
    for j in range(len(pointsB)):
        x,y,tag = pointsB[j]
        value = a * x + b * y + c
        if value > 0:
            sumB += 1
    
    # 判断条件为直线上方只有某一类点的全体
    if (sumA == 0  and sumB == len(pointsB)) or (sumA == len(pointsA)  and sumB == 0):
        print("Yes")
    else:
        print("No")

猜你喜欢

转载自blog.csdn.net/qq_45899597/article/details/113716943