题目:
输入样例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、本题关注点
主要需要弄懂如何判断训练数据汇总的A、B两类点是否分开,判断标准和方法是怎样的。
2、解题思路
判断标准:方程代入点的坐标,>0在上方,<0在下方。
具体思路:
首先每条(m)直线判别时,先将第一个点的类别(A or B)和判断结果(直线的上方 or 下方)作为判定结果的初始值,此后的点(n)的类别和判断的结果与初始不一致则分割失败,失败则立即退出此次判断循环。
比如初始A在上方,B在下方,后续的点也只能A在上方,B在下方,否则就分割失败。
代码展示
/*CFF试题202006-1,试题名称:期线性分类器 Time:20210209*/
/*主要需要弄懂如何判断训练数据汇总的A、B两类点是否分开,判断标准和方法是怎样的*/
/*判断标准:方程代入点的坐标,>0在上方,<0在下方
首先每条(m)直线判别时,先将第一个点的类别(A or B)和判断结果(直线的上方 or 下方)
作为判定结果的初始值,此后的点(n)的类别和判断的结果与初始不一致则分割失败,失败则立即退出此次判断循环
比如初始A在上方,B在下方,后续的点也只能A在上方,B在下方,否则就分割失败*/
/*标准源码获取:清月学习社*/
#include <iostream>
#include<stdio.h>// 包含sort函数
using namespace std;
// 建立点的的结构体
struct Node
{
int x; // 横坐标
int y; // 纵坐标
char type; // 点的类别
};
int main()
{
Node node[1000];
bool sign[20];
// 初始假定完美分割,1-完美分割,0-分割失败
for(int i=0;i<20;i++)
{
sign[i] = true;
}
int m, n;
cin >> n >> m;// 点和方程个数
//输入数据,存到结构体数组中
for(int i=0;i<n;i++)
{
cin >> node[i].x >> node[i].y >> node[i].type;
}
for(int i=0;i<m;i++)
{
int flagA = -1;
int flagB = -1;
int Q1, Q2, Q3;// 方程系数
cin >> Q1 >> Q2 >> Q3;
for(int j=0;j<n;j++)
{
int ans = (Q1 + Q2*node[j].x + Q3*node[j].y) > 0 ? 1 : 0; //1直线上方,0直线下方
if(node[j].type == 'A')// A
{
if(flagA == -1)// 初始化点在直线的哪一边
flagA = ans;
else if(flagA != ans)// 如果后续的不在同一侧,则分割失败
{
sign[i] = false;// 分割失败
break; // 分割失败则不再继续判别,直接跳出此次循环
}
}
else if(node[j].type == 'B')// B
{
if(flagB == -1)// 初始化点在直线的哪一边
flagB = ans;
else if(flagB != ans)// 如果后续的不在同一侧,则分割失败
{
sign[i] = false;// 分割失败
break; // 分割失败则不再继续判别,直接跳出此次循环
}
}
}
}
// 按顺序输出判别结果
for(int i=0;i<m;i++)
{
if(sign[i] == false)
cout << "No" << endl;
else
cout << "Yes" << endl;
}
return 0;
}