线性分类器


from CCF-CSP 2020-06-1
Time limit:1s
Memory limit:512MB

线性分类器_ios


线性分类器_算法_02


线性分类器_算法_03


这是一个数学题目,只需要看一下是否A和B类的点分别在直线的两边,直接将点带入直线,大于0的点都在同一边,而小于0的点在另一边。

这个题我使用了一个小技巧,我们假设A是对应大于0,而B是对应小于0,那么如果大于0并且类别是A或者小于0并且类别是B我们就累加,最后如果能分成两类的话,那么这个累加数一定是n(假设正确)或者0(和假设相反)

if((theta0 + theta1 * p[i].x + theta2 * p[i].y > 0 && p[i].c == 'A') || (theta0 + theta1 * p[i].x + theta2 * p[i].y < 0 && p[i].c == 'B'))
++note;
ac代码:
#include<iostream>
using namespace std;
int n,m;
struct point{
int x,y; //点的坐标
char c; //点的类别
}p[1005];
void solve(){
int theta0,theta1,theta2,note = 0;
cin>>theta0>>theta1>>theta2;
for(int i = 1;i <= n;++i)
if((theta0 + theta1 * p[i].x + theta2 * p[i].y > 0 && p[i].c == 'A') || (theta0 + theta1 * p[i].x + theta2 * p[i].y < 0 && p[i].c == 'B'))
++note;
if(note == 0 || note == n)
cout<<"Yes\n";
else
cout<<"No\n";
}
int main(){
cin>>n>>m;
for(int i = 1;i <= n;++i)
cin>>p[i].x>>p[i].y>>p[i].c;
while(m--)
solve();
return 0;
}