基站選址

問題描述

描述
需要在一個N × M的網格中建立一個通訊基站,通訊基站僅必須建立在格點上。

網格中有A個用戶,每個用戶的通訊代價是用戶到基站歐幾里得距離的平方。

網格中還有B個通訊公司,維護基站的代價是基站到最近的一個通訊公司的路程(路程定義爲曼哈頓距離)。

在網格中建立基站的總代價是用戶通訊代價的總和加上維護基站的代價,最小總代價。

輸入
第一行爲一個整數T,表示數據組數。

每組數據第一行爲四個整數:N, M, A, B。

接下來的A+B行每行兩個整數x, y,代表一個座標,前A行表示各用戶的座標,後B行表示各通訊公司的座標。

輸出
對於每組數據輸出一行”Case #X: Y”,X代表數據編號(從1開始),Y代表所求最小代價。

數據範圍
1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

小數據

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

大數據

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

樣例輸入
2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3
樣例輸出
Case #1: 4
Case #2: 13

思考:只需考慮一個曼哈頓距離,則可對B輸入循環

設(x,y)爲最佳位置,xb,yb 爲最佳的通訊公司位置,則有:
costx=ixi2+ax2+2ixix+|xxb|
costy=iyi2+ay2+2iyiy+|yyb|
cost=costx+costy

從中可以看出,costx 取最小值時, x=ixia±12acosty 同理

代碼

import java.util.Scanner;
/**
 * Created by Risky on 2015/4/19.
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for(int k = 1; k <= n; k++){
            long N = in.nextLong();
            long M = in.nextLong();
            int a = in.nextInt();
            int b = in.nextInt();
            long euDisX = 0, euDisY = 0, manDisX = 0, manDisY = 0;
            for(int i = 0; i < a; i++){
                long xa = in.nextLong();
                long ya = in.nextLong();
                euDisX += xa * xa;    euDisY += ya * ya;
                manDisX += xa;         manDisY += ya;
            }
            long cost = Long.MAX_VALUE;
            for(int j = 0; j < b; j++){
                long temp = Long.MAX_VALUE;
                //long total = 0;
                long xb = in.nextLong();
                long yb = in.nextLong();

                for(long x = manDisX / a - 1; x < manDisX / a + 2; x++){
                    long cx = a * x *x  + euDisX - 2 * manDisX * x  + Math.abs(x - xb);
                    if(cx < temp)
                        temp = cx;
                }
                long total = temp;
                temp = Long.MAX_VALUE;

                for(long y = manDisY / a - 1; y < manDisY / a + 2; y++){
                    long cy = a * y*y  + euDisY - 2 * manDisY * y  + Math.abs(y - yb);
                    if(cy < temp)
                        temp = cy;
                }
                total += temp;
                if(total < cost)
                    cost = total;
            }
            System.out.println("Case #" + k +": "+ cost);

        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章