Color it(找圆内整数点的个数)

题目:在n*m(1<=n<=4e5,1<=m<=4e5)的区域上,有q (q<=200)个圆(xi,yi)半径为r,问有多少整数点没有被盖住。

思路:枚举0到m每个y坐标,然后暴力查询q个圆与y=yi这条线相交的整数点的个数,可以对交出来的线段排序扫一遍,也可以离散一下映射到相应的点上,统计一下就好了。

#include<bits/stdc++.h>
using namespace std;
const int maxn=250;
int n,m,q,t;
struct node{
    int x,y,r;
}p[maxn];
struct node1{
    int l,r;
}a[maxn];
bool cmp(const node1 &a,const node1 &b)
{
    return a.r<b.r;
}
int sum[maxn*4],b[maxn*2];
int main()
{
   // freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=q;i++)
            scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].r);
        int ans=n*m;
        for(int h=0;h<m;h++)
        {
            int cnt=0,tot=0;
            for(int i=1;i<=q;i++)
            {
                if(abs(p[i].y-h)<=p[i].r)
                {
                    int dh=abs(p[i].y-h);
                    int x1=max(int(p[i].x-sqrt(1.0*p[i].r*p[i].r-1.0*dh*dh)),0);
                    if((x1-p[i].x)*(x1-p[i].x)+dh*dh>p[i].r*p[i].r)
                        x1++;
                    int x2=min(int(p[i].x+sqrt(1.0*p[i].r*p[i].r-1.0*dh*dh)),n-1);
                    if((x2-p[i].x)*(x2-p[i].x)+dh*dh>p[i].r*p[i].r)
                        x2--;
                    a[++cnt].l=x1;
                    a[cnt].r=x2;
                    b[++tot]=x1;
                    b[++tot]=x2;
                    b[++tot]=x2+1;
                }
            }
            sort(b+1,b+tot+1);
            int o=unique(b+1,b+tot+1)-b-1;
            int num=0,r=0;
            memset(sum,0,sizeof sum);
            for(int i=1;i<=cnt;i++)
            {
                a[i].l=lower_bound(b+1,b+o+1,a[i].l)-b;
                a[i].r=lower_bound(b+1,b+o+1,a[i].r)-b;
                sum[a[i].l]++;
                sum[a[i].r+1]--;
            }
            int las=1;
            for(int i=1;i<=o;i++)
            {
                sum[i]+=sum[i-1];
                if(sum[i]) num++;
                if(sum[i]&&sum[i-1])
                    num+=b[i]-b[i-1]-1;
            }
            ans-=num;
        }
        printf("%d\n",ans);
    }
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dllpXFire/article/details/81433943