CSP202006-1线性分类器(C++100分)
思路
采用结构体point来保存每个点的坐标x,y以及类别tag。数组res保存每条直线是否可以完美分割。
struct point
{
int x;
int y;
string tag;
};
判断一条直线是否可以完美分割时,首先用start保存第一个点的正负:
start = Z + X * p[0].x + Y * p[0].y;
然后以此为标准判断之后的每一个点是否满足条件。之后的每个点带入到直线中的正负用mid来表示。
mid = Z + X * p[j].x + Y * p[j].y;
当mid和start乘积为正时,说明这两个点在同一侧,那么二者属性tag必须相同,如果不同,则这条直线必定不能完美分割,保存结果到res[ ]中并退出循环即可,检测下一条直线(如果有)。
if (start*mid > 0)
if (p[0].tag == p[j].tag)
continue;
else
{
res[i] = "No";
break;
}
当mid和srart乘积为负时,说明这两个点位于直线两侧,那么二者属性tag必须不同,若相同,则这条直线必定不能完美分割,保存结果到res[ ]中并退出循环即可,检测下一条直线(如果有)。
else
if (p[0].tag != p[j].tag)
continue;
else
{
res[i] = "No";
break;
}
本题有一点需要注意,要采用long long int型数据,否则无法通过测试。
完整代码
#include<iostream>
#include<string>
using namespace std;
struct point
{
int x;
int y;
string tag;
};
struct point p[1100];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> p[i].x >> p[i].y >> p[i].tag;
int Z, X, Y;
long long int start, mid;//这里如果用int会WE
string res[20];
for (int i = 0; i < m; i++)
{
cin >> Z >> X >> Y;
start = Z + X * p[0].x + Y * p[0].y;
for (int j = 1; j <= n; j++)
{
if (j == n)//说明所有的点都可以通过测试,直线符合完美分割条件
{
res[i] = "Yes";
break;
}
mid = Z + X * p[j].x + Y * p[j].y;
if (start*mid > 0)
if (p[0].tag == p[j].tag)
continue;
else
{
res[i] = "No";
break;
}
else
if (p[0].tag != p[j].tag)
continue;
else
{
res[i] = "No";
break;
}
}
}
for (int i = 0; i < m; i++)
cout << res[i] << endl;
}