题解 P4612 【[COCI2011-2012#7] SETNJA】
这题窝了一次,为组织蒙羞(所用人交19,AC15)
那么
I 存储
可以观察到,
那么以便方便我们就用结构体来存
struct node
{
int ux,dx,ly,ry;
}a[400100];
可以记
假设红色的范围是曾经可以待的范围(因为有时候保证最优的不止一个点),
那么每次更新出一个新的范围
而这个范围一定是个矩形,那么之后就说矩形吧(记几
III 如何转移矩形
可以观察出,从当前所在的矩形
共有两种可能:
那么横竖两方向走的少的就可以被抵消,最小步数就是大的那个
呃,不好理解呢,画个图吧
最后
t = Get_((node){t.ux+d,t.dx-d,t.ly-d,t.ry+d},a[i]);ans += (long long )d;
#include <cstdio>
#include <algorithm>
using namespace std;
int N,x,y,p;
struct node
{
int ux,dx,ly,ry;
}a[400100];
node Get_(node a1,node a2)
{
node b = (node){min(a1.ux,a2.ux),max(a1.dx,a2.dx),max(a1.ly,a2.ly),min(a1.ry,a2.ry)};
if(b.ux < b.dx || b.ly > b.ry)return (node){-1,-1,-1,-1};
return b;
}
int main()
{
scanf("%d",&N);
for(int i = 1 ; i <= N ; i ++ )
{
scanf("%d%d%d",&x,&y,&p);
a[i] = (node){x + p,x - p,y - p,y + p};
}
node t = a[1];long long ans = 0;
for(int i = 2 ; i <= N ; i ++ )
{
node b = Get_(a[i],t);
if(b.dx != - 1){t = b;continue;}
int d = max(max(a[i].dx-t.ux,t.dx-a[i].ux),max(a[i].ly-t.ry,t.ly-a[i].ry));
t = Get_((node){t.ux+d,t.dx-d,t.ly-d,t.ry+d},a[i]);ans += (long long )d;
}
printf("%lld",ans);
return 0;
}
其实还可以在化简下
首先结构体变量有两个即可(节能主义万岁!
那么我们使
最后更新下
#include <cstdio>
#include <algorithm>
using namespace std;
int N,x,y,p;
struct node
{
int ux,dx,ly,ry;
}l,now;
int main()
{
scanf("%d",&N);scanf("%d%d%d",&x,&y,&p);
l = (node){x + p,x - p,y - p,y + p};
long long ans = 0;
for(int i = 2 ; i <= N ; i ++ )
{
scanf("%d%d%d",&x,&y,&p);
now = (node){x + p,x - p,y - p,y + p};
int d = max(max(now.dx-l.ux,l.dx-now.ux),max(now.ly-l.ry,l.ly-now.ry));
if(d < 0)d = 0;
ans += (long long)d;
l.dx = max(l.dx - d,now.dx);
l.ux = min(l.ux + d,now.ux);
l.ly = max(l.ly - d,now.ly);
l.ry = min(l.ry + d,now.ry);
}
printf("%lld",ans);
return 0;
}