CSP 202006-1 线性分类器 python

题目描述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

思路

简单来说,就是判断是否能够二分类两条直线,一般来说,如果在直线两侧,分别输入两类,一个是大于0,一个是小于0,有个符号的变换

在这里,如果每次都要判断两次符号,分别计算就比较麻烦,我们可以设置一个标志,就是说如果A点是在直线上方,那么带入就是大于0,A的标志为1,B的标志就为-1,这样子就是得到直线f乘上标志位flag都是大于0的,如果每次都大于0,就说明我们是分对了。

但是我万万没想到,这样只能拿60分,因为还有一个任务,我们要判断一下,A和B是不是都出现过,如果只有一类样本,我们也是输出No

所以最后我们只需要判断f*flag < 0,小于说明没分好类,直接就break退出了

代码

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @File    :   202006-1.py
# @Time    :   2021/11/20 12:24:38
# @Author  :   DKJ
# @Contact :   1016617094@qq.com
# @Software:   VScode

n,m = map(int,input().split(' '))
data = []
for i in range(n):
    # 将输入数据压入data
    data.append(list(input().split(' ')))
    
def f(z,x,y,X,Y):
    # 得到直线方程
    return z + x*X + y*Y

for i in range(m):
    key = {}
    count = {}
    z,x,y = map(int,input().split())
    
    if f(z,x,y,int(data[0][0]),int(data[0][1])) > 0:
        key['A'] = 1
        key['B'] = -1
    else:
        key['A'] = -1
        key['B'] = 1
    flag = 1
    for j in range(1,n):
        # 如果是正确分类的话,满足f*key > 0,key是进行符号变换的
        if f(z,x,y,int(data[j][0]),int(data[j][1])) * key[data[j][2]] < 0:
            flag = 0
            break
        else:
            count[key[data[j][2]]] = 1
    # 子任务,A和B都要存在,如果不存在也是No
    if 'A' and 'B' not in count.keys():
        flag = 0
    if flag:
        print('Yes')
    else:
        print('No')
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐