题意/Description:
在一个N*N的区域玩积木游戏,每个单元格正好跟积木的底面相等,每个单元格里放有若干个积木,Alice想重新摆放积木,使得每个单元格最多只能放一个积木,并且所有积木正好形成一个矩形。
把一个积木从一个位置移到另一个位置称为一次操作。
给出初始状态,编程计算最少需要多少次操作才能达到上述要求。
读入/Input:
第一行包含两个整数N和M(1<=N<=100,1<=M<=N^2),表示区域大小以及积木的数量。
接下来M行,每行包含两个整数R和C(1<=R,C<=N),表示每个积木放置的位置。
输出/Output:
输出最少操作次数。输入保证有解。
题解/solution:
首先要使着成为一个矩形且移动次数最小,那么这个矩形里的积木必须尽量多。然后LZH想起了N年前的打砖块,发现这和这道题几乎一样。于是开心打码,AC。至于怎么打,见程序。
代码/Code:
var
a:array [0..101,0..101] of longint;
n,m,ans:longint;
procedure init;
var
i,j,x,y:longint;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
a[x,y]:=1;
end;
for i:=1 to n do
for j:=1 to n do
a[i,j]:=a[i,j]+a[i-1,j]+a[i,j-1]-a[i-1,j-1];
end;
function maxx(o,p:longint):longint;
begin
if o>p then exit(o);
exit(p);
end;
procedure main;
var
i,j,k,t,max:longint;
begin
ans:=0;
for i:=1 to n do
if m mod i=0 then
begin
t:=m div i;
max:=0;
for j:=i to n do
for k:=t to n do
max:=maxx(a[j,k]-a[j-i,k]-a[j,k-t]+a[j-i,k-t],max);
ans:=maxx(ans,max);
end;
writeln(m-ans);
end;
begin
init;
main;
end.