poj 2318 TOYS 二分+叉积

来源:互联网 发布:时间流失数据法 编辑:程序博客网 时间:2024/06/05 14:42

题解 :

  1. 我们发现这个题目的隔板是按照x从小到大排列的,所以当一个点在某个隔板的左边时它一定也在它右边隔板的左边这样的话这个题在第几个搁板后面就满足了二分性质
  2. 然后我们就可以二分答案,看看每个点在哪两个板中间就可以了
  3. 注意二分的边界,二分时一定要判断两个东西
    1. 判断边界 防止进入死循环
    2. 判断每个点是否都能被访问
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;const int maxn = 5005;int muit (int x1,int y1,int x2,int y2) {    return  x1 * y2 - x2 * y1;}int n,m,x1,x2,y1,y2;int num[maxn] = {0};int ll[maxn] = {0};int rr[maxn] = {0};int main (){    ios_base :: sync_with_stdio(false);    while (cin >> n && n) {        cin >> m >> x1 >> y1 >> x2 >> y2;        ll[0] = rr[0] = x1;        ll[n + 1] = rr[n + 1] = x2;        memset (num,0,sizeof(num));        for (int i = 1;i <= n; ++ i) {            cin >> ll[i] >> rr[i];        }        for (int i = 1;i <= m; ++ i) {            int x,y;            cin >> x >> y;            if (x < x1 || x > x2 || y < y2 || y > y1) continue;            int l = 1;            int r = n + 1;            int mid;            while (r > l) {                mid = (r + l) >> 1;                if (muit(x - ll[mid], y - y1, rr[mid] - ll[mid],y2 - y1) < 0) l = mid + 1;                else r = mid;            }            num[l - 1] ++;        }        for (int i = 0;i <= n; ++ i) {            cout << i << ": " << num[i] << endl;        }        cout << endl;    }    return 0;}
原创粉丝点击