To The Beginning

题目描述
麻婆一股劲的追切丝,追到一个大森林里。切丝看着前面有一块大平地,可以当成是一个n*n的矩阵。其中只有n个面积为1*1的子矩阵上面有树。眼看着麻婆就要赶来了,切丝必须要很快地移动这些树(好强壮!),使得每行每列仅有一棵树,以挡住麻婆的视线。那么他最少要移动多少距离的树呢?他又怎样移动这些树呢?注:每次移动树你可以任选一棵树,但是树只能四方向移动,每移动到一个相邻的子矩阵距离为1。一次只能移动一棵,且不能移动到已经有树的子矩阵里面。
操作方案:”L”:(Y-1) “R”:(Y+1) “U”:(X-1) “D”:(X+1)
输入
第一行仅1个正整数n,为大空地的规格。
接下来n行每行2个正整数,为这n棵树的坐标。
输出
第一行仅1个正整数Ans,为所有树一共最少要被移动多少距离。
接下来Ans行按顺序输出你的方案。任意可行方案皆可。
输出文件保证不会超过0.5M
样例输入
6
1 1
1 2
2 1
5 6
6 5
6 6
样例输出
8
2 D
2 R
3 D
3 R
4 L
4 U
5 L
5 U
提示
[样例解释]
方案已输出,故无样例解释。
[数据范围与约定]
对于10%的数据:n<=5
对于40%的数据:n<=10
对于60%的数据:n<=100
对于100%的数据:2<=n<=500

我们可以贪心的来移动。先按横坐标排序,按照这个排序的位置规定它在第几列,然后先贪心的向某一方向移动,在向另一方向移动,这样就不会重叠。列也是同理。

var
n,i,ans:longint; 
a,b,p,x:array[0..100000] of longint; 
y:array[0..100000] of char; 
procedure sorta(l,r:longint); 
var
i,j,t,m:longint; 
begin
  i:=l;j:=r;m:=a[(i+j) div 2]; 
  repeat
    while a[i]<m do inc(i); 
    while a[j]>m do dec(j); 
    if i<=j then
    begin
      t:=a[i];a[i]:=a[j];a[j]:=t; 
      t:=b[i];b[i]:=b[j];b[j]:=t; 
      t:=p[i];p[i]:=p[j];p[j]:=t; 
      inc(i);dec(j); 
    end; 
  until i>j; 
  if i<r then sorta(i,r); 
  if j>l then sorta(l,j); 
end; 

procedure sortb(l,r:longint); 
var
i,j,t,m:longint; 
begin
  i:=l;j:=r;m:=b[(i+j) div 2]; 
  repeat
    while b[i]<m do inc(i); 
    while b[j]>m do dec(j); 
    if i<=j then
    begin
      t:=a[i];a[i]:=a[j];a[j]:=t; 
      t:=b[i];b[i]:=b[j];b[j]:=t; 
      t:=p[i];p[i]:=p[j];p[j]:=t; 
      inc(i);dec(j); 
    end; 
  until i>j; 
  if i<r then sortb(i,r); 
  if j>l then sortb(l,j); 
end; 
begin
  readln(n); 
  for i:=1 to n do
  begin
    p[i]:=i; 
    read(a[i],b[i]); 
  end; 
  sorta(1,n); 
  for i:=1 to n do
  begin
    while a[i]>i do
    begin
      ans:=ans+1; 
      x[ans]:=p[i]; 
      y[ans]:='U'; 
      a[i]:=a[i]-1; 
    end; 
  end; 
  for i:=n downto 1 do
  begin
    while a[i]<i do
    begin
      ans:=ans+1; 
      x[ans]:=p[i]; 
      y[ans]:='D'; 
      a[i]:=a[i]+1; 
    end; 
  end; 
  sortb(1,n); 
  for i:=1 to n do
  begin
    while b[i]>i do
    begin
      ans:=ans+1; 
      x[ans]:=p[i]; 
      y[ans]:='L'; 
      b[i]:=b[i]-1; 
    end; 
  end; 
  for i:=n downto 1 do
  begin
    while b[i]<i do
    begin
      ans:=ans+1; 
      x[ans]:=p[i]; 
      y[ans]:='R'; 
      b[i]:=b[i]+1; 
    end; 
  end; 
  writeln(ans); 
  for i:=1 to ans-1 do
    writeln(x[i],' ',y[i]); 
  write(x[ans],' ',y[ans]); 
end. 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值