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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章