TOYS POJ - 2318 (二分+斜率)

问题虫洞: TOYS POJ - 2318

 

黑洞内窥:

多组测试,一行六个数n, m, x1, y1, x2, y2;

锁定一个矩阵的左端点为(x1, y1),右下点为(x2, y2),

紧跟着n行,一行两个数a,b,代表(a, y1) 到 (b, y2)之间有一条直线。

n个点n条分割线将矩阵分成了n+1个区域。。。

再接着m个点的座标(x,  y) ,最后输出每个区域的点数。

(注意:点不会落在斜线上,且一定在矩阵内)

 

思维光年:

其实容易想到的是,求出每条分割线的斜率,

然后用m个点的纵座标y去求出每条分割线下对应的x,

由于分割线是从左到右给出的,

所以我们可以遍历一遍所以的分割线,如果 X > Xm

则该点就在该区域内,时间复杂度为O(n*m),

坑点:

我一开始是用全cin 读入,,,上面的复杂度O(n*m),我想也是,理所当然的残忍TLE,

然后我就二分分割线线斜率, 但还是TLE,这让我实在费解。。

最后我把所有的cin改成sacnf,,,,二分代码AC

暴力代码居然也。。。。绿了~~~~~我怀疑我被scanf绿了。。。

警告!警告!警告!:     请使用scanf! 请使用scanf!请使用scanf!

 

ACcode:(二分斜率)

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <map>
#include      <set>
#include   <vector>
#include    <queue>
#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
#include  <sstream>
using namespace std;
typedef long long int ll;
const ll MAXN = 5005;
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 100000007;
const double eps = 0.0000001;

pair<double, double>p[MAXN];
int n, m;
double x1, y1, x2, y2;
int num[MAXN];
double is[MAXN];
int main()
{
    while(cin >> n && n)
    {
        memset(num, 0, sizeof(num));
        memset(is, 0, sizeof(is));
        scanf("%d %lf %lf %lf %lf", &m, &x1, &y1, &x2, &y2);
        for(int i=0; i<n; ++i)
        {
            double a, b;
            scanf("%lf %lf", &a, &b);
            if(a == b)
                is[i] = a;
            else
            {
                p[i].first = (y1-y2)*1.0/(a-b);
                p[i].second = y1*1.0 - p[i].first*a;
            }
        }
        is[n] = x2;
        for(int i=0; i<m; ++i)
        {
            int x, y;
            scanf("%d %d", &x, &y);
            int l=0, r = n;
            while(l <= r)
            {
                int mid = (l+r)/2;
                double ans;
                if(is[mid])
                    ans = is[mid];
                else
                    ans = (y*1.0 - p[mid].second)/ p[mid].first;
                if(ans > x)
                    r = mid-1;
                else
                    l= mid+1;
            }
            num[l]++;
        }
        for(int i=0; i<=n; ++i)
            cout << i << ": " << num[i] << '\n';
        cout << '\n';
    }
    return 0;
}

 

ACcode:(改成scanf的暴力AC)

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <map>
#include      <set>
#include   <vector>
#include    <queue>
#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
#include  <sstream>
using namespace std;
typedef long long int ll;
const ll MAXN = 5005;
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 100000007;
const double eps = 0.0000001;

pair<double, double>p[MAXN];
int n, m;
double x1, y1, x2, y2;
int num[MAXN];
double is[MAXN];
int main()
{
    while(cin >> n && n)
    {
        memset(num, 0, sizeof(num));
        memset(is, 0, sizeof(is));
       scanf("%d %lf %lf %lf %lf", &m, &x1, &y1, &x2, &y2);
        for(int i=0; i<n; ++i)
        {
            double a, b;
            scanf("%lf %lf", &a, &b);
            if(a == b)
            {
                is[i] = a;
            }
            else
            {
                p[i].first = (y1-y2)*1.0/(a-b);
                p[i].second = y1*1.0 - p[i].first*a;
            }
        }
        is[n] = x2;
        for(int i=0; i<m; ++i)
        {
            double x, y;
           scanf("%lf %lf", &x, &y);
            for(int j=0; j<=n; ++j)    //暴力。。。
            {
                double ans;
                if(is[j])
                    ans = is[j];
                else
                    ans = (y*1.0 - p[j].second)/ p[j].first;
                if(ans >= x)
                {
                    num[j]++;
                    break;
                }
            }
        }
        for(int i=0; i<=n; ++i)
        {
            cout << i << ": " << num[i] << '\n';
        }
        cout << '\n';
    }
    return 0;
}

 

发布了165 篇原创文章 · 获赞 35 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章