2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it

本文介绍了一道ACM竞赛中的经典问题——在矩阵中画圆并计算未被染色的格子数量。通过使用扫描线算法来解决该问题,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://www.nowcoder.com/acm/contest/163/F

来源:牛客网

2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

There is a matrix A that has N rows and M columns. Each grid (i,j)(0 ≤ i < N, 0 ≤ j < M) is painted in white at first.
Then we perform q operations:
For each operation, we are given (x c, y c) and r. We will paint all grids (i, j) that meets to black.
You need to calculate the number of white grids left in matrix A.

输入描述:

The first line of the input is T(1≤ T ≤ 40), which stands for the number of test cases you need to solve.
The first line of each case contains three integers N, M and q (1 ≤ N, M ≤ 2 x 10 4; 1 ≤ q ≤ 200), as mentioned above.
The next q lines, each lines contains three integers x
c
, y
c
 and r (0 ≤ x
c
 < N; 0 ≤ y
c
 < M; 0 ≤ r ≤ 10
5
), as mentioned above.

输出描述:

For each test case, output one number.
示例1

输入

复制
2
39 49 2
12 31 6
15 41 26
1 1 1
0 0 1

输出

复制
729
0

题意还是比较简单的,给你n和m的格子让你去画圆,如果这个点在圆内,就要被染色,问你还剩多少点没有被染色

这个题目可以直接暴力扫描线,也就成了维护线段的并

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
vector<pair<int,int> >V[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for(int i=0; i<N; i++)V[i].clear();
        int n,m,q;
        scanf("%d%d%d",&n,&m,&q);
        for(int j=0,x,y,r; j<q; j++)
        {
            scanf("%d%d%d",&x,&y,&r);
            for(int i=max(0,y-r),d; i<=min(m-1,y+r); i++)
                d=(sqrt(r*r-(y-i)*(y-i)+1e-6)),V[i].push_back(make_pair(max(0,x-d),min(x+d,n-1)));
        }
        int s=n*m;
        for(int i=0; i<m; i++)
        {
            int l=V[i].size();
            if(l>0)
            {
                sort(V[i].begin(),V[i].end());
                int r=-1;
                for(auto X:V[i])
                {
                    if(X.second<=r)continue;
                    if(X.first>r) s-=X.second-X.first+1;
                    else s-=X.second-r;
                    r=X.second;
                }
            }
        }
        cout<<s<<"\n";
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/BobHuang/p/9493577.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值