問題描述
越野競賽暑期訓練營近年來報名人數大增,因此訓練營把3公頃大的訓練場隔成 m x n 個相鄰的區域,每兩個相鄰(上、下、左、右)的區域之間都有教練駐守,因此除了用餐時間外,學員不得隨意跨區接受訓練。每天早上雖然營長會將所有人分配到不同的區域進行訓練,到了午餐時,為了避免學員來回奔波,因此會選定某一區搭設臨時帳棚並將所有學員集中到這一區來用餐,當午餐時間到來時,每一區的學員就會自行往用餐區移動。根據以往的經驗,平均來講,每 0.1 秒就可以有一人從自己所在區域移動到一個相鄰的區域(換句話說,每一秒可以有 10 人次轉換至相鄰區域)。為了使所有學員能儘速到達用餐區,請寫一個程式幫營長決定應該將午餐設在哪一區。
範例:
以下圖為例,訓練場已分割成 3 x 5 個區域,其中第(1, 1)區有5個學員、第(3, 4)區有3個學員,而第(1, 3), (2, 1), (2, 3), (2, 5), (3, 2), (3, 3)及(3, 5)區都沒有任何學員。
輸入檔格式(C:\lunch\input.txt)
測試檔案的第一行有兩個數字 m, n, (1 <= m, n <= 100)分別代表訓練場的區隔方式(如上圖所示),因此第 i, j 區的區域代號就是(i, j)。接下來的 m 行,每一行有 n 個整數,這 m 行中的第 i 行的第 j 個整數代表(i, j)區的學員數。每兩個整數之間都會有一個空白。
輸出檔格式 (C:\lunch\output.txt)
請輸出能最快讓所有學員都能集中到達用餐的區域代號。輸出時,不需要輸出括號或逗點,只需要將代表該區的兩個整數輸出並以空白隔開。
輸入檔範例
3 5
5 2 0 2 2
0 2 0 2 0
1 0 0 3 0
輸出檔範例
1 2
解題思考
首先分析題目的意思,我們可以知道,要求的結果是希望讓"所有人的移動區域數總和"為最小的最佳化題目。
至於移動區域數的計算方式,假設現在某甲的位置在(a, b),則某甲移動到(i, j)的移動區域數就等於:|a - i| + |b - j|。
接著,使用暴力法,計算每個區域的移動總格數,求出能得到最小值的地點,就是答案了。
參考解答(C)
#include <stdio.h> #include <stdlib.h> #include <limits.h> int main(void) { int m, n, x, y, fx, fy, i, j, sum, a, b, min = INT_MAX; int** man; // 宣告檔案串流 FILE *in, *out = fopen("C:/lunch/output.txt", "w+"); if (!(in = fopen("C:/lunch/input.txt","r"))) { printf("找不到 input.txt\n"); system("pause"); exit(1); } printf("讀入資料 . . .\n"); fscanf(in, "%d %d", &m, &n); printf("%d %d\n", m, n); // 動態配置記憶體空間 man = (int**)malloc(sizeof(int*) * m); for (i = 0; i < m; i++) { man[i] = (int*)malloc(sizeof(int) * n); for (j = 0; j < n; j++) { fscanf(in,"%d", &man[i][j]); printf("%d ", man[i][j]); } printf("\n"); } fclose(in); for (a = 1; a <= m; a++) { for (b = 1; b <= n; b++) { // 設用餐地點為 (a, b) sum = 0; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { // 求出 (i, j) 區域的人到達 (a, b) 區域的時間 x = (i + 1 - a) > 0 ? (i + 1 - a) : (a - i - 1); y = (j + 1 - b) > 0 ? (j + 1 - b) : (b - j - 1); sum += man[i][j] * (x + y); } } // 求出最小值 if (min > sum) { min = sum; fx = a; fy = b; } } } // 釋放記憶體空間 for (i = 0; i < m; i++) { free(man[i]); } free(man); fprintf(out, "%d %d\n", fx, fy); fclose(out); printf("吃飯地點為 (%d, %d)\n", fx, fy); printf("輸出資料在 ouput.txt\n"); system("pause"); }
0 回覆:
張貼留言