POJ 2318 幾何初步 + 二分 及其 姊妹題 POJ 2398

來源:互聯網
上載者:User

叉積+二分

如果toys在當前板的左邊 cross(L,toys,U) < 0

反之在右邊會 > 0

根據這個,我們進行二分;

為什麼最後得到的不是mid而是l呢?

我們來看這張圖.

加入現在是 l = 2 , r = 5;mid = 3; toy在4紙板右邊,5紙板左邊,

執行l = l +1 = 3, r = 5, mid = 4;依然>0 執行, 

l = l + 1 = 4,r = 5, mid = 4; 依然大於0 ,執行

l = l + 1 = 5, r= 5, 退出; 此時l = 5, 之前toy確實在l右邊,可是現在在它左邊了.(有的情況還是會在右邊)

所以我們後面要加一個判斷:

if(cross(CardB[r].L, Toys, CardB[r].U) < 0)        N_Toys[l]++;else        N_Toys[l+1]++;

顯然,我們同樣可以:

if(cross(CardB[r].L, Toys, CardB[r].U) > 0)        N_Toys[r+1]++;else        N_Toys[r]++;

那麼,如果利用mid 改怎麼改寫代碼呢?

        for(int i = 0; i < m; i++)        {            l = 0, r = n-1;            scanf("%d%d",&Toys.x,&Toys.y);            while(l <= r)            {                mid = (l + r) >> 1;                if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0)                    l = mid + 1;                else                    r = mid - 1;            }            if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0)                N_Toys[mid+1]++;            else                N_Toys[mid]++;        }

/* *POJ 2318 *fuqiang *幾何初步 *2013/8/2*/#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 5000+3;const double PI = 4.0*atan(1.0);const double eps = 1e-8;struct point{    int x;    int y;} Toys;struct Line{    point U;    point L;} CardB[maxn];int N_Toys[maxn];int cross(const point &p0, const point &p1, const point &p2)  //計算叉積{    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int main(){#ifndef ONLINE_JUDGE    freopen("in","r",stdin);#endif    int n,m,x1,y1,x2,y2;    while(scanf("%d",&n) && n)    {        scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);        for(int i = 0; i < n; i++)        {            scanf("%d%d", &CardB[i].U.x, &CardB[i].L.x);            CardB[i].U.y = y1;            CardB[i].L.y = y2;        }        memset(N_Toys,0,sizeof(N_Toys));        int l, r, mid, ans, p;        for(int i = 0; i < m; i++)        {            l = 0, r = n-1;            scanf("%d%d",&Toys.x,&Toys.y);            while(l < r)            {                mid = (l + r) >> 1;                if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0)                    l = mid + 1;                else                    r = mid;            }            if(cross(CardB[r].L, Toys, CardB[r].U) < 0)                N_Toys[l]++;            else                N_Toys[l+1]++;        }        for(int i = 0; i <= n; i++)        {            printf("%d: %d\n",i,N_Toys[i]);        }        printf("\n");    }}

還有個更好的點子,別人的代碼:

將最後一個點也作為紙板,此時 我們只需要返回l:

while (l <= r){    mid = (l + r) >> 1;    if ( cal (low[mid], high[mid], cc) > 0 )        l = mid + 1;    else r = mid - 1;    }    return l;}

POJ 2398

加個排序,統計後輸出,注意t>0

/* *POJ 2318 *fuqiang *幾何初步 *2013/8/2*/#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 5000+3;const double PI = 4.0*atan(1.0);const double eps = 1e-8;struct point{    int x;    int y;} Toys;struct Line{    point U;    point L;} CardB[maxn];int N_Toys[maxn];int cross(const point &p0, const point &p1, const point &p2)  //計算叉積{    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int cmp(Line a, Line b)//sort...{    return a.L.x < b.L.x;}int main(){#ifndef ONLINE_JUDGE    freopen("in","r",stdin);#endif    int n,m,x1,y1,x2,y2;    while(scanf("%d",&n) && n)    {        scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);        for(int i = 0; i < n; i++)        {            scanf("%d%d", &CardB[i].U.x, &CardB[i].L.x);            CardB[i].U.y = y1;            CardB[i].L.y = y2;        }        sort(CardB,CardB+n,cmp); //sort        memset(N_Toys,0,sizeof(N_Toys));        int l, r, mid, ans, p;        for(int i = 0; i < m; i++)        {            l = 0, r = n-1;            scanf("%d%d",&Toys.x,&Toys.y);            while(l <= r)            {                mid = (l + r) >> 1;                if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0)                    l = mid + 1;                else                    r = mid - 1;            }            if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0)                N_Toys[mid+1]++;            else                N_Toys[mid]++;        }        sort(N_Toys,N_Toys+n+1);        printf("Box\n");        int st = 0;        while(N_Toys[st] == 0)            st++;        for(int i = st; i <= n; )        {            int num = 1;            printf("%d: ",N_Toys[i]);            for(int j = i++; j <= n; j++,i++)            {                if(N_Toys[i]==N_Toys[j])                    num++;                else                    break;            }            printf("%d\n",num);        }//        printf("\n");    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.