• TOYS-POJ2318


    本题主要是确定给定的点在那块区域。原题给出n条直线,将长方形分为n+1快区域。我们可以对每个给定的点来判断它在那块区域,判段方法可以根据点与直线的位置关系,具体如下,对于点(x0,y0)和直线ax+by+c=0(a>0):

         1)若a*x0+b*y0+c=0,则点在直线上。

         2)若a*x0+b*y0+c>0,则点在直线右侧。

         3)若a*x0+b*y0+c<0,则点在直线左侧。

    顺序查找点的位置必然会耗费大量的时间。所以采用二分方法,找到点所在的区间,然后累计起来。下面代码将ax+by+c=0化简为x+(b/a)y+(c/a)=0,默认x的系数为1.

    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<string>
    #include<queue>
    #include<cmath>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int MAXN = 5001;
    struct Line{
    	double b, c;   //x+b*y+c=0
    };
    Line L[MAXN];
    int Count[MAXN];
    int BinFind(int x,int y,int n);
    int main(){
    	int x1, y1, x2, y2,s,t,n,m,i,x,y,id,c=1;
    	while (scanf("%d", &n)&&n){
    		if (c != 1)  //控制下格式
    			cout << endl;
    		c++;
    		scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
    		memset(Count, 0, sizeof(Count));
    		L[0].b = 0, L[0].c = 0 - x1;   //第一条直线应该是矩形左边的一条边
    		for (i = 0; i < n; i++){
    			scanf("%d%d", &s, &t);
    			L[i+1].b = (t - s)*1.0/(y1 - y2);
    			L[i+1].c = (y2*s - t*y1)*1.0 / (y1 - y2);
    		}
    		L[n + 1].b = 0, L[n + 1].c = 0 - x2;      //最后一条直线应该是矩形右边那条边
    		for (i = 0; i < m; i++){
    			scanf("%d%d", &x, &y);
    			id = BinFind(x, y, n);
    			Count[id]++;
    		}
    		for (i = 0; i <= n; i++)
    			cout << i << ": " << Count[i] << endl;
    	}
    	return 0;
    }
    int BinFind(int x, int y,int n){
    	int left = 0, right = n+1; 
    	while (left < right-1){    //找到的点在区间(L[left],L[rigth])之间
    		int mid = (left + right) >> 1;
    		if (x + L[mid].b*y + L[mid].c>0)  //点在直线右边
    			left = mid;
    		else
    			right = mid;
    	}
    	return left;
    }
    

      

  • 相关阅读:
    Python数据爬虫,爬链家的二手房信息
    驼峰命名法
    变量
    use strict(变得严格)
    注释
    分号(line break:分行符号)
    使用外部js文件
    confirm
    prompt
    https和http的区别
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5686621.html
Copyright © 2020-2023  润新知