Description:
在一个N*N的区域玩积木游戏,每个单元格正好跟积木的底面相等,每个单元格里放有若干个积木,Alice想重新摆放积木,使得每个单元格最多只能放一个积木,并且所有积木正好形成一个矩形。
把一个积木从一个位置移到另一个位置称为一次操作。
给出初始状态,编程计算最少需要多少次操作才能达到上述要求。
Input
第一行包含两个整数N和M(1<=N<=100,1<=M<=N^2),表示区域大小以及积木的数量。
接下来M行,每行包含两个整数R和C(1<=R,C<=N),表示每个积木放置的位置。
Output
输出最少操作次数。输入保证有解。
Solution
Fi,j
为点
(i,j)
的被积木所占的个数前缀和。
枚举矩形长
i
,则宽
j
为
j=mi
再枚举矩形右下角,利用前缀和得出需移步数。
Program
Pascal
var
i,j,n,m,r,c,x,y,k:longint;
f,bj:array[0..100,0..100]of longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a)else exit(b);
end;
procedure did;
begin
for x:=1to round(sqrt(m))+1do
begin
if m mod x>0then continue;
y:=m div x;
for i:=x to n do
for j:=y to n do
k:=min(k,m-(f[i,j]-f[i-x,j]-f[i,j-y]+f[i-x,j-y]));
end;
writeln(k);
end;
procedure Theprefixand;
begin
for i:=1to n do
for j:=1to n do
f[i,j]:=f[i,j]+f[i-1,j]+f[i,j-1]-f[i-1,j-1]+bj[i,j];
end;
begin
read(n,m);
for i:=1to m do
begin
read(r,c);
f[r,c]:=1;
end;
Theprefixand;
k:=maxlongint;
did;
end.