堆棋子

小易將n個棋子擺放在一張無限大的棋盤上。第i個棋子放在第x[i]行y[i]列。同一個格子允許放置多個棋子。每一次操作小易可以把一個棋子拿起並將其移動到原格子的上、下、左、右的任意一個格子中。小易想知道要讓棋盤上出現有一個格子中至少有i(1 ≤ i ≤ n)個棋子所需要的最少操作次數.
input:
輸入包括三行,第一行一個整數n(1 ≤ n ≤ 50),表示棋子的個數
第二行爲n個棋子的橫座標x[i](1 ≤ x[i] ≤ 10^9)
第三行爲n個棋子的縱座標y[i](1 ≤ y[i] ≤ 10^9)
output:
輸出n個整數,第i個表示棋盤上有一個格子至少有i個棋子所需要的操作數,以空格分割。行末無空格

如樣例所示:
對於1個棋子: 不需要操作
對於2個棋子: 將前兩個棋子放在(1, 1)中
對於3個棋子: 將前三個棋子放在(2, 1)中
對於4個棋子: 將所有棋子都放在(3, 1)中
樣例輸入:
4
1 2 4 9
1 1 1 1
樣例輸出:
0 1 3 10

import java.util.PriorityQueue;
import java.util.Scanner;
public class Main{
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        int cheeseNum=in.nextInt();
        int[] x=new int[cheeseNum];
        int[] y=new int[cheeseNum];
        //輸入
        for(int i=0;i<cheeseNum;i++)
        {
            x[i]=in.nextInt();
        }
        for(int i=0;i<cheeseNum;i++)
        {
            y[i]=in.nextInt();
        }
        int[] result=new Main().getOperaterCount(x,y,cheeseNum);
        for(int i=0;i<cheeseNum-1;i++)
        {
            System.out.print(result[i]+" ");
        }
        System.out.print(result[cheeseNum-1]);
    }
    public int[] getOperaterCount(int[] x,int[] y,int cheeseNum)
    {
        int[] resArray=new int[cheeseNum];
        //將所有值賦爲最大值 用於記錄棋盤中有棋子的節點到可能爲棋子彙集位置的距離
        //resArray[0]表示格子中只有一個節點時需要進行操作的最少次數  爲什麼 往下看
        for(int i=0;i<cheeseNum;i++)
        {
            resArray[i]=Integer.MAX_VALUE;
        }
        PriorityQueue<Integer> queue=new PriorityQueue<>();//有序隊列 省去排序過程
        int index=0;//用於遍歷
        int sum=0;
        //聚集點的橫座標肯定是原棋子橫座標的其中一個 縱座標同理 以證明
        //所以這個雙重循環用來遍歷所有可能的聚集點
        for(int i=0;i<cheeseNum;i++)
        {
            for(int j=0;j<cheeseNum;j++)
            {
                //接下來這個循環 用於查找所有棋子到當前聚集點的距離
                for(int k=0;k<cheeseNum;k++)
                {
                    queue.add(Math.abs(x[k]-x[i])+Math.abs(y[k]-y[j]));
                }
                //隊列中記錄所有棋子到(x[i],y[j])的距離 且按照升序排序
                index=0;//刷新resArray數組
                sum=0;//到達聚集點的棋子數 resArray[i] i+1顆棋子到(x[i],y[j])的最短距離
                while(!queue.isEmpty())
                {
                    sum+=queue.poll();
                    //更新過程 格子中有i個棋子時,i不同時,聚集點也可能不同
                    resArray[index]=Math.min(resArray[index],sum);
                    index++;
                }
            }
        }
        return resArray;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章