PAT 乙級 採花生 (模擬)
---------------------------------處女blog------------------------逃…
題目描述
魯賓遜先生有一隻寵物猴,名叫多多。這天,他們兩個正沿著鄉間小路散步,突然發現路邊的告示牌上貼著一張小小的紙條:“歡迎免費品嚐我種的花生!——熊字”。
魯賓遜先生和多多都很開心,因為花生正是他們的最愛。在告示牌背後,路邊真的有一塊花生田,花生植株整齊地排列成矩形網格。有經驗的多多一眼就能看出,每棵花生植株下的花生有多少。為了訓練多多的算術,魯賓遜先生說:“你先找出花生最多的植株,去採摘它的花生;然後再找出剩下的植株裡花生最多的,去採摘它的花生;依此類推,不過你一定要在我限定的時間內回到路邊。”
我們假定多多在每個單位時間內,可以做下列四件事情中的一件:
1. 從路邊跳到最靠近路邊(即第一行)的某棵花生植株;
2. 從一棵植株跳到前後左右與之相鄰的另一棵植株;
3. 採摘一棵植株下的花生;
4. 從最靠近路邊(即第一行)的某棵花生植株跳回路邊。
現在給定一塊花生田的大小和花生的分佈,請問在限定時間內,多多最多可以採到多少個花生?
注意可能只有部分植株下面長有花生,假設這些植株下的花生個數各不相同。例如花生田裡只有位於(2, 5), (3,7), (4, 2), (5, 4)的植株下長有花生,個數分別為 13, 7, 15, 9。多多在 21 個單位時間內,只能經過(4, 2)、(2, 5)、(5, 4),最多可以採到37 個花生。
輸入描述:
輸入包含多組資料,每組資料第一行包括三個整數 M(1≤M≤20)、N(1≤N≤20)和 K(0≤K≤1000),用空格隔開;表示花生田的大小為 M * N,多多采花生的限定時間為 K個單位時間。
緊接著 M 行,每行包括 N 個自然數 P(0≤P≤500),用空格隔開;表示花生田裡植株下花生的數目,並且除了0(沒有花生),其他所有植株下花生的數目都不相同。
輸出描述:
對應每一組資料,輸出一個整數,即在限定時間內,多多最多可以採到花生的個數。
輸入例子:
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
輸出例子:
37
--------------------------------------------------------solution-----------------------------------------------
#include <stdio.h> int next_step1(int first, int second) { //計算採花生的兩個點,行之間的距離 if (first / 100>second / 100) return (first / 100 - second / 100); else return (second / 100 - first / 100); } int next_step2(int first, int second) { //計算採花生的兩個點,列之間的距離 if (first % 100>second % 100) return (first % 100 - second % 100); else return (second % 100 - first % 100); } int main() { int m, n, k = 0, i, j; while (scanf("%d%d%d", &m, &n, &k) != EOF) { //輸入陣列 int a[20][20], b[400], c[400]; for (i = 0; i<m; i++) for (j = 0; j<n; j++) scanf("%d", &a[i][j]); int q = 0, maxq = 0, temptb = 0, temptc = 0; for (i = 0; i<m; i++) //二維陣列轉換為一維陣列 b for (j = 0; j<n; j++) { b[q] = a[i][j]; c[q] = i * 100 + j; //二維陣列換算,把下標進行換算 ”行*100+列“並存儲到一維陣列c中 q++; } for (maxq = 0; maxq<m*n; maxq++) //一維陣列b和c排序,從大到小 { for (q = 0; q<m*n; q++) if (b[q]<b[maxq]) { temptb = b[maxq]; b[maxq] = b[q]; b[q] = temptb; temptc = c[maxq]; c[maxq] = c[q]; c[q] = temptc; } } //計算在k值下,最短路徑 int step = 0, carrot = 0, fstep = 0; int next_step1(int first, int second); int next_step2(int first, int second); if ((c[0] / 100 * 2 + 3)>k) printf("%d\n", carrot); else { step = c[0] / 100 + 2; carrot = carrot + b[0]; for (q = 1; q<m*n; q++) { //這裡要注意迴圈結束的條件 step = step + next_step1(c[q], c[q - 1]) + next_step2(c[q], c[q - 1]); if ((step + 2 + c[q] / 100)>k) break; step = step + 1; carrot = carrot + b[q]; } printf("%d\n", carrot); } } return 0; }
---------------------------------------------思路總結--------------
因為沒有學過任何的演算法之類的,是最近才開始撿起扔了兩年的C語言的,因此用的是最笨的方法,暴力解。
首先是將花生田放入二維陣列中,然後將二維陣列轉換為一維陣列,對一維陣列進行排序,當然,在二維與一維的轉換過程中需要建立另一個數組,對花生的座標進行記錄,為保證記錄的座標資料在後面可以用來計算採花生的步數,由於題設要求行列不超過20,所以我採用了對行進行加權,用行x100,列保持不變。對加權後的座標陣列元素,可以得到類似301、102等資料,如301表示,該花生在第三行,第一列,計算301到102需要移動的步數為301的百位數減去102的百位數,即3-1=2,剩下的個、十位數相減,即為列之間的步數02-01=1,所以從301走到102共需要1+2=3步,在做減法的時候,需要先將座標資訊提取,然後取相減的絕對值,即大的減小的。此外,還需注意一些細節問題,即迴圈的結束條件等。