CCF-CSP认证 线性分类器(含爆内存风险!!)

#include 
using namespace std;
struct Point{
     
    int x;
    int y;
};
const int N=1e3+10;
Point a[N];
Point b[N];
int main(){
     
    int n,m,x1,y1,f=0,g=0;
    char t;
    cin>>n>>m;
    for(int k=0;k<n;++k){
     
        cin>>x1>>y1>>t;
        if(t=='A'){
     
            a[f].x=x1;
            a[f].y=y1;
            ++f;
        }
        else{
     
            b[g].x=x1;
            b[g].y=y1;
            ++g;
        }       
    }//分为两个集合,f-1、g-1为两类点的数量
    for(int i=0;i<m;++i){
     
        int q,w,e;
        cin>>q>>w>>e;
        long long temp=q+w*a[0].x+e*a[0].y;
        long long temp1=q+w*b[0].x+e*b[0].y;
        bool flag=true,flag1=true,flag2=true;
        for(int j=1;j<f-1;++j){
     
            long long temp2=q+(long long )w*a[j].x+(long long )e*a[j].y;
            if(temp*temp2<0){
     
                cout<<"No";
                if(i!=m-1) cout<<endl;
                flag=false;
                break;
            }
        }
        for(int j=1;j<g-1&&flag;++j){
     
            long long temp3=q+(long long )w*b[j].x+(long long )e*b[j].y;
            if(temp1*temp3<0){
     
                cout<<"No";
                if(i!=m-1) cout<<endl;
                flag1=false;
                break;                
            }
        }
        if(flag&&flag1&&(long long )(q+w*a[0].x+e*a[0].y)*(long long )(q+w*b[0].x+e*b[0].y)>0){
     
            cout<<"No";
            if(i!=m-1) cout<<endl;
            flag2=false;
        }
        if(flag&&flag1&&flag2){
     //所有条件均满足才是yes
            cout<<"Yes";
            if(i!=m-1) cout<<endl;
        }
    }
    return 0;
}

易错点:
由于三个系数和输入的x、y坐标值都<=10^6 相乘时可能会出现爆内存的情况,因此要使用long long而不是int!

思路:
1、保证A类各点都在直线同一侧,B同理
2、保证A、B两集合在直线两侧

当A有任意两点不在同一侧时,break跳出当前循环,当A各点都在直线同一侧时再判断B各点是否都在直线同一侧,若是,再判断A、B集合是否在直线两侧。

你可能感兴趣的:(ccf-csp)