用的是赛前集训时提到的贪心,当时说某些题目用贪心可以得部分分,但是本题贪心可以得满分的。
当然本题的贪心需要预处理下,开2个一维数组,row[i]录如果在第i行加通道,可以分割多少对调皮学生,col[i]记录如果在第j列加通道,可以分割多少对调皮学生,最后贪心法输出分割学生最多的前K行和前L列。
参考程序:
program seat;
const
inp='seat.in';
oup='seat.out';
var
flag,m,n,k,l,d,i,j,x,y,x1,y1:longint;
tmp,col,row:array[1..1000] of longint;
s,s1:ansistring;
procedure flink;
begin
assign(input,inp);
reset(input);
assign(output,oup);
rewrite(output);
end;
procedure fclose;
begin
close(input);
close(output);
end;
function min(a,b:longint):longint;
begin
if a end;
procedure qsort(m,n:Longint);//快排
var
i,j,k,t:longint;
begin
i:=m; j:=n; k:=tmp[(i+j) shr 1];
repeat
while tmp[i]>k do inc(i);
while tmp[j]
begin
t:=tmp[i]; tmp[i]:=tmp[j]; tmp[j]:=t;
inc(I); dec(J);
end;
until i>j;
if m
begin
flink;
readln(m,n,k,L,d);
fillchar(row,sizeof(row),0);
fillchar(col,sizeof(col),0);
for i:= 1 to d do //统计在每行、每列添加通道可以分割的学生数
begin
readln(x,y,x1,y1);
if (x=x1)
then inc(col[min(y,y1)])
else inc(row[min(x,x1)]);
end;
j:=0;
for i:= 1 to m do //把能没个行通道分割的学生数加入tmp数组,准备排序
begin
if row[i]>0 then
begin
inc(j);
tmp[j]:=row[i];
end;
end;
qsort(1,j);//对tmp数组排序
flag:=tmp[k];//flag为前K项的最小值
i:=1; j:=0;
while (i<=n) and (j
if row[i]>=flag then //如果该行能分割的人数不少于flag,说明此处可以添加通道
begin
write(i);
inc(j);
if j<>k then write(' ');
end;
inc(i);
end;
writeln;
//下面是求列通道,思想同上
j:=0;
for i:= 1 to n do
begin
if col[i]>0 then
begin
inc(j);
tmp[j]:=col[i];
end;
end;
qsort(1,j);
flag:=tmp[L];
i:=1; j:=0;
while (i<=m) and (j
if col[i]>=flag then
begin
write(i);
inc(j);
if j<>L then write(' ');
end;
inc(i);
end;
fclose;
end.