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()