POJ 1230 Pass-Muraille 贪心

来源:互联网 发布:周立功单片机培训 编辑:程序博客网 时间:2024/06/07 16:04

题目链接:http://poj.org/problem?id=1230


题目大意:魔术师在舞台上表演穿墙术,舞台可视为由若干个单位为一的正方形组成的矩形。输入为n和k,n表示舞台上墙的总数目,k为魔术师的能量,即最多可以穿过k堵墙,接着输入每堵墙的端点坐标(s.x,s.y)、(e.x, e.y),每堵墙长度不定,宽度为1,即s.y=e.y。求最少需要去除多少堵墙才能使魔术师演出顺利。


题目解析:贪心策略。从左到右,依次枚举每一列i,判断当前列的墙的数目x[i]是否大于k,如果大于k,则移除(x[i]-k)个包含当前列且向右延伸最长的墙。需要注意的一点是:输入每堵墙的端点坐标可能会出现e.x > s.x的情况。


程序源码:

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int MAXN = 110;struct Node {    int x;    int y;};struct Pair {    Node s;    Node e;}p[MAXN];int x[MAXN];bool flag[MAXN];int main() {    int t;    cin >> t;    while (t--) {        int n, k;        cin >> n >> k;        memset(x, 0, sizeof(x));        memset(flag, 0, sizeof(flag));        for (int i = 1; i <= n; i++) {            cin >> p[i].s.x >> p[i].s.y >> p[i].e.x >> p[i].e.y;            if (p[i].s.x > p[i].e.x) {                p[i].s.x ^= p[i].e.x;                p[i].e.x ^= p[i].s.x;                p[i].s.x ^= p[i].e.x;            }            for (int j = p[i].s.x; j <= p[i].e.x; j++) {                x[j]++;            }        }        int ans = 0;        for (int i = 0; i <= 100; i++) {            while (x[i] > k) {                int maxLen = 0, pos = 0;                for (int j = 1; j <= n; j++) {                    if ((!flag[j]) && p[j].s.x <= i && p[j].e.x >= i) {                        if (maxLen < p[j].e.x) {                            maxLen = p[j].e.x;                            pos = j;                        }                    }                }                flag[pos] = true;                ans ++;                for (int j = p[pos].s.x; j <= p[pos].e.x; j++) {                    x[j]--;                }            }        }        cout << ans << endl;    }    return 0;}



0 0