题目链接:https://vjudge.net/problem/%E8%AE%A1%E8%92%9C%E5%AE%A2-43370
题目大意:给你一个数S,代表直线的数目。接下来S行,每行四个整数,表示直线的两个坐标,即x1,y1,x2,y2;
任何两条直线不会重合。这些直线将平面进行划分为多个区域,区域是"residential"或者"commercial";直线两侧的区域要不同。接下来给你一个数T,表示要进行查询的数目,接下来T行,即T组查询,每行四个整数,即x1,y1,x2,y2;让你判断这两个数是否会在相同的区域"residential"或者"commercial"。
思路:刚开始看这个题,觉着很难,认为是个平面划分的题目,弄了好长时间也没弄出来。后来,就找的规律。
由直线上的两个点可以确定直线的方程。你只需要判断这两个点分别位于多少条直线的上方,若同为奇数或偶数,则在相同区域,否则,不在相同区域。
附上AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#define cla(a, sum) memset(a, sum, sizeof(a))
#define rap(i,m,n) for(i=m;i<=n;i++)
#define rep(i,m,n) for(i=m;i>=n;i--)
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef pair<ll,ll>P;
const int Inf=0x3f3f3f3f;
const double eps=1e-6;
const int maxn=1e4+5;
int s,t;
struct node{
int x0,y0;
int x2,y2;
}f[maxn];
//判断是否位于直线上方
bool check(int x,int y,int a,int aa,int b,int bb)
{
return (y-aa)*(b-a)-(bb-aa)*(x-a)>0;
}
int main()
{
cin>>s;
int i,j,k;
rap(i,1,s){
scanf("%d%d%d%d",&f[i].x0 ,&f[i].y0 ,&f[i].x2 ,&f[i].y2 );
}
cin>>t;
int sum1,sum2;
int x,y,xx,yy;
while(t--)
{
sum1=sum2=0;
scanf("%d%d%d%d",&x,&y,&xx,&yy);
rap(i,1,s){
if(check(x,y,f[i].x0 ,f[i].y0 ,f[i].x2 ,f[i].y2 )){
sum1++;
}
if(check(xx,yy,f[i].x0 ,f[i].y0 ,f[i].x2 ,f[i].y2 )){
sum2++;
}
}
if(sum1%2==sum2%2){
printf("same\n");
}
else {
printf("different\n");
}
}
return 0;
}