燈光照射,圓形探測類問題(解題報告)<分層差分><cmath取整>
阿新 • • 發佈:2019-04-20
radi 分層 bsp name min lock 前綴 pan str
題目描述
一個n*n的網格圖上有m個探測器,每個探測器有個探測半徑r,問這n*n個點中有多少個點能被探測到。
輸入輸出格式
輸入格式:
(1<=r<n<=5000)
(1<=m<=5000)
第一行3個整數n,m,r
接下來m行,每行兩個整數x,y表示第i個探測器的坐標
輸出格式:
能被探測到的點的個數
輸入輸出樣例
輸入樣例#1: 復制5 2 1 3 3 4 2
輸出樣例#1: 復制8
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int an[5002][5002];
double longth (int r,int d)
{
return sqrt(r*r-d*d);
}
int main ()
{
int n,m,r,x,y,ln,rn,listr,listl;
int ans=0;
cin>>n>>m>>r;
for(int i=0;i<m;i++)
{
cin>>x>>y;
ln =max(x-r,1);//上邊界
rn=min(x+r,n);//下邊界
for(int j=ln;j<=rn;j++)//列數
{
listl=max(1,(int)ceil(y-longth(r,x-j)));//左邊界//是將此坐標整體進行向下取整
listr=min(n,(int)floor(y+longth(r,x-j)));//右邊界//同理
an[j][listl]+=1;//差分標記
an[j][listr+1]-=1;
}
}
for(int i=1;i<=n;i++)//前綴和後遍歷取0(統計零解多次探照問題)//反向計數
for (int j = 1; j <= n; j++)
{
an[i][j] += an[i][j - 1];
if (an[i][j]==0)
ans++;
}
cout<<n*n-ans<<endl;
return 0;
}
燈光照射,圓形探測類問題(解題報告)<分層差分><cmath取整>