1. 程式人生 > >燈光照射,圓形探測類問題(解題報告)<分層差分><cmath取整>

燈光照射,圓形探測類問題(解題報告)<分層差分><cmath取整>

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取整>