题目大意
给定一个平面坐标系,其中有 n 个整点。给定一个多边形,求在给定范围内,有多少个位置可以放这个多边形,满足多边形内没有给定的整点。
Data Constraint
题解
先用射线法做出一个bitset矩阵,记录那些点在多边形内。
然后原图建一个bitset,枚举多边形左下角的位置,暴力bitset and一下。
时间复杂度: O(Xp432)
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<cmath>
using namespace std ;
#define N 250000 + 10
#define M 500 + 10
struct DOT {
int x , y ;
DOT ( int X = 0 , int Y = 0 ) { x = X , y = Y ; }
} fly[N] , P[N] ;
bitset < M > Map[M] , POL[M] , tmp ;
bool flag[M][M] ;
int S[M][M] ;
int Xp , Yp , n , Num , ans ;
int Minx , Miny , Maxx , Maxy ;
int main() {
freopen( "fly.in" , "r" , stdin ) ;
freopen( "fly.out" , "w" , stdout ) ;
scanf( "%d%d%d" , &Xp , &Yp , &n ) ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf( "%d%d" , &fly[i].x , &fly[i].y ) ;
Map[fly[i].x][fly[i].y] = 1 ;
}
Minx = Miny = 0x7FFFFFFF ;
Maxx = Maxy = -0x7FFFFFFF ;
scanf( "%d" , &Num ) ;
for (int i = 1 ; i <= Num ; i ++ ) {
scanf( "%d%d" , &P[i].x , &P[i].y ) ;
Minx = min( Minx , P[i].x ) ;
Miny = min( Miny , P[i].y ) ;
}
for (int i = 1 ; i <= Num ; i ++ ) {
P[i].x -= Minx ;
P[i].y -= Miny ;
Maxx = max( Maxx , P[i].x ) ;
Maxy = max( Maxy , P[i].y ) ;
}
for (int k = 1 ; k <= Num ; k ++ ) {
int i = k , j = k % Num + 1 ;
if ( P[i].x > P[j].x ) swap( i , j ) ;
if ( P[i].x == P[j].x ) {
for (int l = min( P[i].y , P[j].y ) ; l <= max( P[j].y , P[i].y ) ; l ++ ) flag[P[i].x][l] = -1 ;
continue ;
}
double del = (double)(P[j].y - P[i].y) / (P[j].x - P[i].x) ;
double y = P[i].y ;
for (int l = P[i].x ; l <= P[j].x ; l ++ , y += del ) {
int now = y ;
if ( fabs(y-(double)now) <= 1e-6 ) flag[l][now] = 1 ;
if ( l < P[j].x ) S[l][now+1] ++ ;
}
}
for (int x = 0 ; x <= Maxx ; x ++ ) {
for (int y = 1 ; y <= Maxy ; y ++ ) S[x][y] += S[x][y-1] ;
}
for (int x = 0 ; x <= Maxx ; x ++ ) {
for (int y = 0 ; y <= Maxy ; y ++ ) {
if ( flag[x][y] || (S[x][y] & 1) ) {
POL[x][y] = 1 ;
}
}
}
for (int x = 0 ; x <= Xp - Maxx ; x ++ ) {
for (int y = 0 ; y <= Yp - Maxy ; y ++ ) {
bool ok = 1 ;
for (int i = 0 ; i <= Maxx ; i ++ ) {
tmp = POL[i] & (Map[x+i] >> y) ;
if ( tmp.any() ) { ok = 0 ; break ; }
}
ans += ok ;
}
}
printf( "%d\n" , ans ) ;
return 0 ;
}
以上.