CCF之最優配餐(java)
阿新 • • 發佈:2019-01-04
試題編號: | 201409-4 |
試題名稱: | 最優配餐 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述
棟棟最近開了一家餐飲連鎖店,提供外賣服務。隨著連鎖店越來越多,怎麼合理的給客戶送餐成為了一個急需解決的問題。 棟棟的連鎖店所在的區域可以看成是一個n×n的方格圖(如下圖所示),方格的格點上的位置上可能包含棟棟的分店(綠色標註)或者客戶(藍色標註),有一些格點是不能經過的(紅色標註)。 方格圖中的線表示可以行走的道路,相鄰兩個格點的距離為1。棟棟要送餐必須走可以行走的道路,而且不能經過紅色標註的點。 送餐的主要成本體現在路上所花的時間,每一份餐每走一個單位的距離需要花費1塊錢。每個客戶的需求都可以由棟棟的任意分店配送,每個分店沒有配送總量的限制。 現在你得到了棟棟的客戶的需求,請問在最優的送餐方式下,送這些餐需要花費多大的成本。 輸入格式 輸入的第一行包含四個整數n, m, k, d,分別表示方格圖的大小、棟棟的分店數量、客戶的數量,以及不能經過的點的數量。 接下來m行,每行兩個整數xi, yi,表示棟棟的一個分店在方格圖中的橫座標和縱座標。 接下來k行,每行三個整數xi, yi, ci,分別表示每個客戶在方格圖中的橫座標、縱座標和訂餐的量。(注意,可能有多個客戶在方格圖中的同一個位置) 接下來d行,每行兩個整數,分別表示每個不能經過的點的橫座標和縱座標。 輸出格式 輸出一個整數,表示最優送餐方式下所需要花費的成本。 樣例輸入 10 2 3 3 1 1 8 8 1 5 1 2 3 3 6 7 2 1 2 2 2 6 8 樣例輸出 29 評測用例規模與約定 前30%的評測用例滿足:1<=n <=20。 前60%的評測用例滿足:1<=n<=100。 所有評測用例都滿足:1<=n<=1000,1<=m, k, d<=n^2。可能有多個客戶在同一個格點上。每個客戶的訂餐量不超過1000,每個客戶所需要的餐都能被送到。 |
解題程式碼(java):
import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { static class Vertex implements Cloneable { public int x; public int y; public int step; public Vertex(int x, int y, int step) { this.x = x; this.y = y; this.step = step; } public Vertex() { } } public static void main(String[] args) { long[][] map = new long[1001][1001]; Queue<Vertex> q = new LinkedList<Vertex>(); boolean[][] vis = new boolean[1001][1001]; int[][] move = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; Scanner in = new Scanner(System.in); long size = in.nextLong(); long m = in.nextLong(); long k = in.nextLong(); long d = in.nextLong(); for (int i = 0; i < m; i++) { int x = in.nextInt(); int y = in.nextInt(); int step = 0; q.add(new Vertex(x, y, step)); } for (int i = 0; i < k; i++) { int x = in.nextInt(); int y = in.nextInt(); int z = in.nextInt(); map[x][y] = z; } for (int i = 0; i < d; i++) { int x = in.nextInt(); int y = in.nextInt(); vis[x][y] = true; } in.close(); long cnt = 0; long ans = 0; while (!q.isEmpty()) { Vertex u = q.remove(); for (int i = 0; i < 4; i++) { Vertex tem = new Vertex(); tem.x = u.x; tem.y = u.y; tem.step = u.step; tem.x += move[i][0]; tem.y += move[i][1]; tem.step++; if (tem.x > 0 && tem.y <= size && tem.y > 0 && tem.x <= size && !vis[tem.x][tem.y]) { vis[tem.x][tem.y] = true; if (map[tem.x][tem.y] != 0) { ans += map[tem.x][tem.y] * tem.step; ++cnt; if (cnt == k) break; } q.add(tem); } } } System.out.println(ans); } }
得分80 ,歡迎指正