線上OJ:
【04NOIP普及組】花生采摘
核心思想:
1、本題為貪心即可。
2、因為本題嚴格限制了順序,所以先把每個節點的花生數量按降序排序。然后逐一判斷下一個花生是否需要去采摘即可
3、每一次采摘完,記錄耗時 t 以及采集的花生總數 ans。同時考慮排序后的下一個節點,如果采摘后返回路邊時間足夠,則執行下一次采摘;如果采摘后來不及返回路邊,則不再進行下一次采摘,本次直接返回路邊即可。
4、注意,第一次是否需要采摘可進行特判。for 循環中從花生第二多的節點開始
題解代碼:
#include <bits/stdc++.h>
using namespace std;const int N = 405;struct Node
{int x, y; // 第x行,第y列int n; // 的花生數量為n
};
Node node[N];bool cmp(Node a, Node b)
{return a.n > b. n; // 降序排序
}int m, n, k, cnt=0; // cnt用于記載node的數量int main()
{scanf("%d %d %d", &m, &n, &k);for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++){node[++cnt].x = i; // 存儲行node[cnt].y = j; // 存儲列scanf("%d", &node[cnt].n); // 存儲花生數量}sort(node + 1, node + 1 + cnt, cmp); // 對所有的節點按照n進行降序排序if(2 * node[1].x + 1 > k) // 如果采集第一次就無法返回,則輸出0{printf("0\n");return 0;}int t = node[1].x + 1; // 如果第一次采集時間足夠,則用t記錄第一次采集已經耗費的時間,記得要把采摘的+1時間也算上int ans = node[1].n; // ans記錄已經采集的花生總數for(int i = 2; i <= cnt; i++){ // 如果從當前i-1到下一個i,時間不足以完成走路+采摘+回到路邊,則到此結束if(t + abs(node[i].x - node[i-1].x) + abs(node[i].y - node[i-1].y) + 1 + node[i].x > k)break;else // 如果從當前i-1到下一個i時間夠,則,采摘第i個{t += abs(node[i].x - node[i-1].x) + abs(node[i].y - node[i-1].y) + 1; // 更新耗費時間tans += node[i].n; // 更新采摘數量 ans}}printf("%d\n", ans);return 0;
}