题解:P17040 [NWERC 2021] Dyson Circle
lailai0916 · · 题解
题意简述
平面上给出若干星星格。选择尽量少的单位格作为屏障,使所有星星位于同一个四连通有限区域内,并且该区域不能通过边与无限外部相连。屏障格之间只需至少共用一个角。
解题思路
使用旋转后的坐标:
原网格中的每个格子满足
记所有星星在
先证明下界。设某个方案的内部连通区域为
屏障的外边界中存在一条由不同屏障格组成的简单闭合链,记长度为
沿闭合链走一周。任意坐标从最小值走到最大值并回到最小值,总变化量至少是极差的两倍。再利用相邻屏障格的坐标变化,可以得到:
所以任意方案至少需要:
还需处理退化情形。若
下面给出达到下界的构造。先在
当
若
因此最终答案为
正确性证明
任意可行屏障都包含围住内部区域的闭合外边界。闭合链在
非退化时,变换坐标最小矩形中的合法格点构成四连通内部,其外侧四邻格形成一条闭合屏障,数量为
参考代码
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
int mn[2]={inf,inf};
int mx[2]={-inf,-inf};
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
int v[2]={x+y,x-y};
for(int j=0;j<2;j++)
{
mn[j]=min(mn[j],v[j]);
mx[j]=max(mx[j],v[j]);
}
}
int d[2]={mx[0]-mn[0],mx[1]-mn[1]};
int ans=d[0]+d[1]+4;
if(n>1&&(!d[0]||!d[1]))ans++;
cout<<ans<<'\n';
return 0;
}