1. 程式人生 > >POJ #1230 Pass-Muraille 貪心

POJ #1230 Pass-Muraille 貪心

rip open display com int counter urn 特殊 main

Description


  問題在這:鏈接

  測試樣例在這:鏈接

  還有些特殊的測試樣例需要測試,可以在題目下的 DISCUSS 裏翻一翻。

思路


  問題概述如下:

    技術分享圖片

  

  我們需要考慮,如何拆墻才是最優的。是拆最長的墻的嗎?並不是的,因為最長的墻可能對之後要走的列沒有幫助。如何讓拆掉的墻對之後的列幫助最大呢?最優的辦法就是讓拆掉的墻的右端盡可能的長,那麽當魔術師走之後的列的時候FQ就會更少。

    技術分享圖片

  代碼如下,雖然WA,但是過了DISCUSS中的所有測試樣例,之後想到了會再改:

技術分享圖片
#include<iostream>
#include<algorithm>
#include
<cstring> #include<vector> using namespace std; #define INT_MIN -9999 bool map[MAX_X + 1][MAX_Y + 1]; //true 有墻, false 無墻 int n, k; //總墻數與魔術師能翻過的墻數 struct Point { int x; int y; }; struct Wall { Point start; Point end; bool remove_flag; }; int greedy_remove (const int& max_x, const
int& max_y, vector<Wall>& w) { //cout << " 進入 greedy_remove "<< max_x << " " << max_y << " " << n << " " << k << endl; int remove_counter = 0; for (int i = 0; i <= max_x; i++) { int energy = k; for (int j = 0
; j <= max_y; j++) { if (!map[i][j]) continue; else if (map[i][j] && energy) { energy--; continue; } else if (map[i][j] && !energy) { int dist = INT_MIN; //阻礙前進的墻的最右端到當前位置的距離 int num = INT_MIN; //需要刪除的墻的序號 for (int m = 1; m <= n; m++) { if (!w[m].remove_flag && w[m].end.x >= i && w[m].start.x <= i) { int dist2 = w[m].end.x - i; //貪心選擇當前列到墻最右端最遠的墻 if (dist < dist2) { num = m; dist = dist2; } } } //刪墻 if (num != INT_MIN) { for (int i2 = w[num].start.x; i2 <= w[num].end.x; i2++) { map[i2][w[num].start.y] = false; } w[num].remove_flag = true; remove_counter++; } } } //j <= max_y } //i <= max_x return remove_counter; } //int greedy_remove() int main(void) { int t; cin >> t; vector<Wall> w; while (t--) { cin >> n >> k; //建墻 memset(map, 0, sizeof(map)); int max_x = INT_MIN, max_y = INT_MIN; w.resize(n+1); for (int i = 1; i <= n; i++) { int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; if (x1 <= x2) { for (int j = x1; j <= x2; j++){ map[j][y1] = true; } w[i].start.x = x1; w[i].start.y = y1; w[i].end.x = x2; w[i].end.y = y2; bool remove_flag = false; } else if (x1 > x2){ for (int j = x2; j <= x1; j++) { map[j][y2] = true; } w[i].start.x = x2; w[i].start.y = y2; w[i].end.x = x1; w[i].end.y = y1; bool remove_flag = false; } if (max_x < std::max(x1, x2)) { max_x = std::max(x1, x2); } if (max_y < std::max(y1, y2)) { max_y = std::max(y1, y2); } } //貪心刪墻 int ans = greedy_remove(max_x, max_y, w); w.clear(); vector<Wall>().swap(w); cout << ans << endl; } return 0; } //int main()
View Code

POJ #1230 Pass-Muraille 貪心