扫描线 - UVALive - 6864 Strange Antennas

 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\n", 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\n", res);
                  ans += res;
            }
            printf( "%d \n " , 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 \n " , ans);
      }
      return 0;
}
/*

*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值