题目:NLO (模拟)
在Žabnik村的当地人多年来一直与UFO进行斗争,UFO在稻田里创造了许多个圆圈,这种行为在夏天割草是尤其明显。
让我们想象一个由n行m列组成的矩形稻田,左上角坐标为(1,1),右下角坐标为(n,m)。每块稻田内都有一定数量的草,最初,所有稻田的草量都等于1,在K天内,圆形UFO每天都降落在地上,在地面盘旋,在第i天一早,半径为Ri的UFO在坐标(xi,yi)的稻田上着陆,收割掉UFO覆盖的稻田上的所有草,换句话说,如果坐标(x,y)在(xi-x)2+(yi-y)2≤Ri2内,那么坐标(x,y)中所有的稻田草量都将变为0。当新的一天到来时,所有稻田的草量都增加1.
在第k天的傍晚,当地人将收割所有的草并存储用来喂牛,问他们能收到多少的草?
输入格式
第一行输入两个数N和M,表示稻田的行数和列数(1≤n,m≤100000)
第二行输入一个数K(1≤K≤100),UFO在当地人收割草前降落的天数。
接下来K行,每行输入三个数字xi,yi,Ri(1<xi<n,1<yi<m,1≤Ri≤min(xi-1,yi-1,n-xi,m-yi)),表示第i天降落的UFO的坐标和半径。
输出格式
答案输出一行,表示当地人最多能收到的草的数量。
样例
样例输入1
6 6
3
4 4 2
3 3 2
2 4 1
样例输出1
68
样例输入2
100 100
2
50 50 49
30 30 29
样例输出2
9534
样例输入3
33333 44444
1
11111 22222 9999
样例输出3
1167355751
思路:
首先这道题不能强行在数组上进行修改,因为无论是空间还是时间都会爆。
我们思考对于每一个圆形,那些点是必须要的,很明显只有圆边上的边我们需要记忆。
接着就考虑两个圆相交的情况,其实也很简单,将这个圆划分成一列一列的就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
long long u;
long long d;
long long t;
node(){}
node(long long U,long long D,long long T):u(U),d(D),t(T){};
};
long long n,m;
long long k;
long long ans;
vector<node> v[100005];
void update(long long lie,long long u,long long d,long long _index)
{
for(int i=0,siz=v[lie].size();i<siz;i++)
{
if(u<=v[lie][i].u&&v[lie][i].u<=d&&d<v[lie][i].d)
{
v[lie].push_back(node(d+1,v[lie][i].d,v[lie][i].t));
v[lie].erase(v[lie].begin()+i);
siz--;
i--;
}
else if(v[lie][i].u<u&&d<v[lie][i].d)
{
v[lie].push_back(node(v[lie][i].u,u-1,v[lie][i].t));
v[lie].push_back(node(d+1,v[lie][i].d,v[lie][i].t));
v[lie].erase(v[lie].begin()+i);
siz--;
i--;
}
else if(u>v[lie][i].u&&u<=v[lie][i].d&&v[lie][i].d<=d)
{
v[lie].push_back(node(v[lie][i].u,u-1,v[lie][i].t));
v[lie].erase(v[lie].begin()+i);
siz--;
i--;
}
else if(u<=v[lie][i].u&&v[lie][i].d<=d)
{
v[lie].erase(v[lie].begin()+i);
siz--;
i--;
}
}
v[lie].push_back(node(u,d,_index));
}
int main()
{
cin>>n>>m>>k;
ans=n*m*k;
for(int i=1;i<=k;i++)
{
long long a,b,r;
cin>>a>>b>>r;
for(int y=max(1ll,b-r);y<=min(m,b+r);y++)
{
long long u;
long long v;
u=max((long long)ceil(-sqrt((r+y-b)*(r-y+b))+a),1ll);
v=min((long long)floor(sqrt((r+y-b)*(r-y+b))+a),n);
update(y,u,v,i);
}
}
for(int i=1;i<=m;i++)
{
for(int j=0;j<v[i].size();j++)
{
ans=ans-(v[i][j].d-v[i][j].u+1)*v[i][j].t;
}
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号