Urban Design--计蒜客 - 43370 (计算几何思维题)

题目链接: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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值