堆棋子 ( 网易2018校招内推编程题)

来源:互联网 发布:mac dns设置成什么值 编辑:程序博客网 时间:2024/05/18 12:28

  • 题目概要
    • 输入描述
    • 输出描述
    • 如样例所示
  • 分析
  • AC 代码

题目概要

小易将n个棋子摆放在一张无限大的棋盘上。第i个棋子放在第x[i]行y[i]列。同一个格子允许放置多个棋子。每一次操作小易可以把一个棋子拿起并将其移动到原格子的上、下、左、右的任意一个格子中。小易想知道要让棋盘上出现有一个格子中至少有i(1 ≤ i ≤ n)个棋子所需要的最少操作次数.

输入描述:

输入包括三行,第一行一个整数n(1 ≤ n ≤ 50),表示棋子的个数
第二行为n个棋子的横坐标x[i](1 ≤ x[i] ≤ 10^9)
第三行为n个棋子的纵坐标y[i](1 ≤ y[i] ≤ 10^9)

输出描述:

输出n个整数,第i个表示棋盘上有一个格子至少有i个棋子所需要的操作数,以空格分割。行末无空格

如样例所示:

对于1个棋子: 不需要操作
对于2个棋子: 将前两个棋子放在(1, 1)中
对于3个棋子: 将前三个棋子放在(2, 1)中
对于4个棋子: 将所有棋子都放在(3, 1)中

示例1

输入

41 2 4 91 1 1 1

输出

0 1 3 10

分析

xy轴其实是独立的,先只考虑x坐标,采用反证法,假设把k个棋子堆到x0(x0不为任意一个棋子坐标)格子所用的步骤最少。 a个棋子初始在x0的左边,b个棋子初始在x0的右边.左边到x0的总距离为A,右边到x0的总距离为B.

  • 如果a>b,那么对于最靠近x0左边的棋子坐标x[a]来说(假设x[a]与x0的距离为da,那么以x[a]坐标为基准现在的总距离为[(A+B)-da*a+da*b]<A+B,这k个棋子到x[a]的步数会更少;

  • 同理对于b>a的情况,那么对于最靠近x0右边的棋子坐标x[b]的目标将比x0更优。

  • 如果a=b,x[a]、x0、x[b]的步数是一样的。因此,最终汇聚棋子的x坐标只要在棋子初始的x个坐标中考虑


AC 代码

import java.util.Arrays;import java.util.Scanner;public class Main{       public static void main(String[] args){        Scanner scan=new Scanner(System.in);        final int n=scan.nextInt();        int []x=new int[n];        int []y=new int[n];        int i,j,k,l;        for(i=0;i<n;i++)            x[i]=scan.nextInt();        for(j=0;j<n;j++)            y[j]=scan.nextInt();        long []result=new long[n];        result[0]=0;         //(Xj,Yk)到第i个棋子的距离,(Xi,Yi)与(Xj,Yk)为相同坐标时也要计算,此时他们的距离为0.        long [][][]distance=new long[n][n][n];        for(i=0;i<n;i++){            for(j=0;j<n;j++){                for(k=0;k<n;k++){                    distance[j][k][i]=Math.abs(x[i]-x[j])+Math.abs(y[i]-y[k]);                }            }        }        //(Xj,Yk)到所有棋子距离从小到大排序,计算k个棋子最小距离的关键步骤,要理解为什么排序        for(j=0;j<n;j++){            for(k=0;k<n;k++){                Arrays.sort(distance[j][k],0,n);            }        }        //k个棋子放置一起所需要的最小距离        for(i=1;i<n;i++){         long min=Long.MAX_VALUE;         for(j=0;j<n;j++){             for(k=0;k<n;k++){                 long curLength=0;                 for(l=0;l<i+1;l++){                     curLength+=distance[j][k][l];                 }                 min=Math.min(curLength,min);             }         }            result[i]=min;        }        StringBuilder str=new StringBuilder();        for(i=0;i<n;i++)            str.append(result[i]+" ");        str.deleteCharAt(str.length()-1);        System.out.print(str);    }}