【CSP试题回顾】202006-1-线性分类器(优化)

本文介绍了如何使用线性分类器解决CSP问题,通过MyPoint结构表示点,读取并处理输入数据,根据直线方程分类点,最后判断直线能否有效区分不同类型的点。
摘要由CSDN通过智能技术生成

CSP-202006-1-线性分类器

解题思路

1.数据结构

  • 代码使用了一个名为 MyPoint 的结构体来表示空间中的点。这个结构体包含三个属性:xy 表示点的坐标,type 表示点的类型。点的类型用整数表示,类型 ‘A’ 用 0 表示,类型 ‘B’ 用 1 表示。这种方式简化了后续的逻辑判断。

2.输入处理

  • 程序首先读取两个整数 nmn 是给定的点的总数,m 是需要处理的查询(即直线)的总数。
  • 对于每一个点,程序通过输入读取其坐标 (x, y) 和类型 (type)。类型是以字符形式给出的,在存储到 MyPoint 结构体中时,会转换为整数(‘A’ 转换为 0,‘B’ 转换为 1)。
  • 所有这些点被存储在一个名为 listvector<MyPoint> 容器中,便于后续遍历和分类。

3.处理查询

  • 对于每个查询(即每条直线),程序读取三个整数 t0t1t2,这些整数定义了直线的方程 t0 + t1 * x + t2 * y = 0
  • 程序初始化两个集合 set0set1,用于记录被当前直线分隔的两边各自存在哪些类型的点。
  • 程序遍历所有点,对于每个点,根据直线方程计算 t0 + t1 * x + t2 * y 的值:
    • 如果结果大于0,表示该点在直线的一侧,程序将这个点的类型添加到 set0 中。
    • 如果结果小于或等于0,表示该点在直线的另一侧,程序将这个点的类型添加到 set1 中。
  • 这样,每个集合中包含了相应侧的点的类型,可以有0、1或2种类型(因为点的类型只有 ‘A’ 和 ‘B’)。

4.输出结果

  • 在对所有点进行分类后,程序检查 set0set1 中包含的点的类型。
  • 如果任一集合中同时包含类型 ‘A’ 和类型 ‘B’ 的点(即该集合的大小等于2),这意味着当前的直线不能将两种类型的点完全分开,因此程序输出 “No”。
  • 如果每个集合中都只包含一种类型的点(或者一个集合为空),这意味着当前直线能够将类型 ‘A’ 和类型 ‘B’ 的点分开,因此程序输出 “Yes”。

完整代码

#include <iostream>
#include <vector>
#include <set>
using namespace std;

struct MyPoint
{
    long long x, y, type; // A-0 B-1
};

long long n, m, x, y, t0, t1, t2;
char type;
vector<MyPoint>list;

int main() {
    cin >> n >> m;
    for (size_t i = 0; i < n; i++)
    {
        cin >> x >> y >> type;
        if (type == 'A') list.push_back({ x,y,0 });
        else if (type == 'B') list.push_back({ x,y,1 });
    }
    for (size_t i = 0; i < m; i++)
    {
        cin >> t0 >> t1 >> t2;
        set<long long>set0, set1;
        for (auto& it : list)
        {
            if (t0 + t1 * it.x + t2 * it.y > 0) set0.insert(it.type);
            else set1.insert(it.type);
        }
        if (set0.size() == 2) cout << "No\n";
        else if (set1.size() == 2) cout << "No\n";
        else cout << "Yes\n";
    }
    return 0;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值