1 条题解
-
0
思路
通过观察样例和阅读题面,我们发现了以下性质。
-
图像的紧凑性只取决于 的值。
这里的 是在竖直方向上距离最远的点之间的格子数。
这里的 是在水平方向上距离最远的点之间的格子数。
-
向上平移与向下平移本质上是一样的,只会改变图像竖直方向上的相对位置并改变 的值。
向左平移与向右平移本质上是一样的,只会改变图像水平方向上的相对位置并改变 的值。
两类操作互不影响,可以分开来看。
-
根据第二条,可以得出达到最小紧凑性所需的最小按钮点击次数取决于 。
是达到当前 值所需的最小步骤。
是达到当前 值所需的最小步骤。
根据第二条性质,我们知道向上(或向下)和向左(或向右)两类操作互不影响,可以分开来看。以向上(或向下)操作为例。
因为 的值只取决于竖直方向上距离最远的点之间的格子数,所以我们可以先对 数组进行排序。
当第 点从最上面移动到最下面,因为我们不可能真的修改每一个点的位置,它的位置我们不妨认为是 ,我们可以令 ,就做到了断环成链,这时的 数组显然是升序的。于是 ,当最上面的点为 时,都可以用 到 表示。
我们发现在平移的过程中,只有当有图像向上移动到最下面一行的对应单元格中时,即最上面的点改变时, 的值才可能改变。
记当前最上面的点为 ,,此时竖直方向上距离最远的点之间的格子数为 (包括端点,所以加一),分以下情况讨论:
-
当 ,直接跳过。
-
当 ,就有可能更新 的值,而想要用尽可能少的步骤使第 个点为最上面的点,要么是前 个点向上移动 ,要么是第 个点向下平移 (向下移动 是到矩形的最下端,还要加一才能到最上端)。
即 。
-
当 ,令 ,。
另一种情况同理。
细节
-
十年 OI 一场空,不开 long long 见祖宗。
-
注意初始化。
代码
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; long long h,w,k; long long r[N*2],c[N*2]; long long x=1e18,y=1e18,sumx=1e18,sumy=1e18; int main(){ scanf("%lld%lld%lld",&h,&w,&k); for(int i=1;i<=k;i++){ scanf("%lld%lld",&r[i],&c[i]); r[i+k]=r[i]+h;c[i+k]=c[i]+w; } r[0]=0;c[0]=0; sort(r+1,r+1+k*2); sort(c+1,c+1+k*2); for(int i=1;i<=k;i++){ long long res=r[i+k-1]-r[i]+1; if(x>=res){ if(x==res) sumx=min(min(sumx,r[i-1]),h-r[i]+1); else{ x=res; sumx=min(r[i-1],h-r[i]+1); } } } for(int i=1;i<=k;i++){ long long res=c[i+k-1]-c[i]+1; if(y>=res){ if(y==res) sumy=min(min(sumy,c[i-1]),w-c[i]+1); else{ y=res; sumy=min(c[i-1],w-c[i]+1); } } } printf("%lld %lld",x*y,sumx+sumy); } -
- 1
信息
- ID
- 7335
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者