• 扫描线


     Strange Antennas

    Problem's Link:  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=87213


     

    Mean: 

    给你一个N*N的网格,有M个雷达,每个雷达的扫射区域是一个直角边长为P的等腰直角三角形,能够向以直角顶点为中心的四个象限扫射。

    雷达之间存在信号屏蔽,只有被奇数个雷达扫射到的区域才能被信号覆盖。求被信号覆盖的区域是多少。

    analyse:

    因为给的都是整数点,这样就不涉及到计算几何了。

    N的范围是0~3000,M的范围是1~100。

    总的思路是:对N*N的网格做一维遍历(随便哪一维都行)。假设我们选取横向遍历,那么对于每一个竖列,我们对所有的雷达进行判断,判断是否经过这个数列。

    如果经过,计算出在这个数列的长度,用一个数组存起来。每扫一列,对这一列的线段做一次扫描线,加到answer中,扫完即得最终答案。

    Time complexity: O(N*M)

     

    Source code: 

    代码1:

    /*
    * this code is made by crazyacking
    * Verdict: Accepted
    * Submission Date: 2015-08-08-22.04
    * Time: 0MS
    * Memory: 137KB
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #define  LL long long
    #define  ULL unsigned long long
    using namespace std;

    const int MAXN = 30005,MAXM = 105;
    void scan(int &x)
    {
         x=0;
         char c=getchar();
         while(!(c>='0' && c<='9'  || c=='-')) { c=getchar(); }
         bool flag=1;
         if(c=='-')
         {
               flag=0; c=getchar();
         }
         while(c>='0' && c<='9')
         {
               x=x*10+c-'0'; c=getchar();
         }
         if(!flag) { x=-x; }
    }
    void scan2(int &x,int &y) { scan(x),scan(y);}
    void scan3(int &x,int &y,int &z) { scan(x),scan(y),scan(z); }
    /**************************************END     define***************************************/
    struct Event
    {
         int x, val;
         Event() {}
         Event(int _x, int _val) : x(_x), val(_val) {}
         bool operator < (const Event &a) const
         {
               return x < a.x || (x == a.x && val < a.val);
         }
    };

    int n, m;
    int x[MAXM],y[MAXM],p[MAXM],d[MAXM];
    char str[10];

    Event event[MAXM * 2];

    int main()
    {
         while(scanf("%d", &n) != EOF)
         {
               scan(m);
               for(int i = 0; i < m; ++i)
               {
                     scan2(x[i],y[i]),scan2(p[i],d[i]);
                     if(d[i] == 0) --y[i];
                     if(d[i] == 2) --x[i];
                     if(d[i] == 3) --x[i],--y[i];
               }
               int ans = 0;
               for(int i = 0; i < n; ++i)
               {
                     int cntEvent = 0;
                     for(int j = 0; j < m; ++j)
                     {
                           int low = -1, high = -1,len;
                           if(d[j] == 0 && x[j] <= i && i <= x[j] + p[j] - 1)
                           {
                                 len = p[j] - (i - x[j]);
                                 low = max(y[j] - len + 1, 0);
                                 high = y[j];
                           }
                           if(d[j] == 1 && x[j] <= i && i <= x[j] + p[j] - 1)
                           {
                                 len = p[j] - (i - x[j]);
                                 low = y[j];
                                 high = min(y[j] + len - 1, n - 1);
                           }
                           if(d[j] == 2 && x[j] - p[j] + 1 <= i && i <= x[j])
                           {
                                 len = p[j] - (x[j] - i);
                                 low = y[j];
                                 high = min(y[j] + len - 1, n - 1);
                           }
                           if(d[j] == 3 && x[j] - p[j] + 1 <= i && i <= x[j])
                           {
                                 len = p[j] - (x[j] - i);
                                 low = max(y[j] - len + 1, 0);
                                 high = y[j];
                           }
                           if(low != -1 && high != -1 && low <= high)
                           {
    //                              printf( "%d %d ", low, high );
                                 event[cntEvent++] = Event(low, 1);
                                 event[cntEvent++] = Event(high + 1, -1);
                           }
                     }
                     sort(event, event + cntEvent);
                     int res = 0,sum = 0;
                     for(int j = 0; j < cntEvent; ++j)
                     {
                           if((sum & 1))
                                 res += event[j].x - event[j - 1].x;
                           sum += event[j].val;
                     }
    //                  printf("%d ", res);
                     ans += res;
               }
               printf("%d ", ans);
         }
         return 0;
    }

    代码2:

    /*
    * this code is made by crazyacking
    * Verdict: Accepted
    * Submission Date: 2015-08-08-13.52
    * Time: 0MS
    * Memory: 137KB
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #define  LL long long
    #define  ULL unsigned long long
    using namespace std;
    const int MAXN=205;
    int n,m;

    void scan(int &x)
    {
         x=0;
         char c=getchar();
         while(!(c>='0' && c<='9'  || c=='-')) { c=getchar(); }
         bool pos=1;
         if(c=='-')
         {
               pos=0; c=getchar();
         }
         while(c>='0' && c<='9')
         {
               x=x*10+c-'0'; c=getchar();
         }
         if(!pos) { x=-x; }
    }
    void scan2(int &x,int &y) { scan(x),scan(y);}
    void scan3(int &x,int &y,int &z) { scan(x),scan(y),scan(z); }
    /**************************************END     define***************************************/

    struct Tra
    {
         int x,y,p,k;
         int x1,x2,y1,y2;
         int xd,yd;
    }d[MAXN];

    struct Line
    {
         int pos,flag;
    } Li[2*MAXN];
    int cnt;
    bool cmp(Line a,Line b)
    {
         return a.pos<b.pos;
    }
    int main()
    {
         ios_base::sync_with_stdio(false);
         cin.tie(0);
         while(~scanf("%d",&m))
         {
               scan(n);
               for(int i=1;i<=n;++i)
               {
                     int x,y,p,k;
                     scan(x),scan(y),scan(p),scan(k);
                     d[i].x=x,d[i].y=y,d[i].p=p,d[i].k=k;
                     if(k==0)
                     {
                           d[i].x1=x,d[i].x2=x+p;
                           d[i].y1=y-p,d[i].y2=y;
                           d[i].xd=x+p,d[i].yd=y;
                     }
                     else if(k==1)
                     {
                           d[i].x1=x,d[i].x2=x+p;
                           d[i].y1=y,d[i].y2=y+p;
                           d[i].xd=x+p,d[i].yd=y;
                     }
                     else if(k==2)
                     {
                           d[i].x1=x,d[i].x2=x-p;
                           d[i].y1=y,d[i].y2=y+p;
                           d[i].xd=x,d[i].yd=y+p;
                     }
                     else
                     {
                           d[i].x1=x,d[i].x2=x-p;
                           d[i].y1=y-p,d[i].y2=y;
                           d[i].xd=x,d[i].yd=y-p;
                     }
               }
               int ans=0;
               for(int yi=0;yi<m;++yi)
               {
                     int from ,to ,t,xt;
                     cnt=0;
                     for(int i=1;i<=n;++i)
                     {
                           if(d[i].y1<=yi&&yi+1<=d[i].y2)
                           {
                                 if(d[i].k<=1) from=to=d[i].x>d[i].x2?d[i].x2:d[i].x;
                                 else from=to=d[i].x1>d[i].x2?d[i].x1:d[i].x2;

                                 t=abs(d[i].yd-yi);
                                 xt=d[i].xd-t;
                                 from=from<xt?from:xt;
                                 to=to>xt?to:xt;

                                 t=abs(d[i].yd-(yi+1));
                                 xt=d[i].xd-t;
                                 from=from<xt?from:xt;
                                 to=to>xt?to:xt;

                                 from=from>0?from:0;
                                 from++;
                                 to=to<m?to:m;
                                 cnt++;
                                 Li[cnt].pos=from;
                                 Li[cnt].flag=+1;

                                 cnt++;
                                 Li[cnt].pos=to+1;
                                 Li[cnt].flag=-1;
                           }
                     }
                     cnt++;
                     Li[cnt].pos=m+1;
                     sort(Li+1,Li+1+cnt,cmp);
                     int lastpos=1,num=0;
                     for(int i=1;i<=cnt;)
                     {
                           if(num&1) ans+=Li[i].pos-lastpos;
                           lastpos=Li[i].pos;
                           int ti=i;
                           while(ti<=cnt&&Li[ti].pos==Li[i].pos)
                           {
                                 num+=Li[ti].flag;
                                 ti++;
                           }
                           i=ti;
                     }
               }
               printf("%d ",ans);
         }
         return 0;
    }
    /*

    */
  • 相关阅读:
    SDL 开发实战(三):使用 SDL 绘制基本图形
    SDL 开发实战(二):SDL 2.0 核心 API 解析
    SDL 开发实战(一):SDL介绍及开发环境配置
    开源播放器 ijkplayer (六) :Android 下使用 ijkplayer 异常处理思路
    音视频编解码技术(二):AAC 音频编码技术
    FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据
    FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据
    FFmpeg开发实战(三):FFmpeg 打印音视频Meta信息
    FFmpeg开发实战(二):FFmpeg 文件操作
    FFmpeg开发实战(一):FFmpeg 打印日志
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4713921.html
Copyright © 2020-2023  润新知