码迷,mamicode.com
首页 > 其他好文 > 详细

POJ #1230 Pass-Muraille 贪心

时间:2018-02-11 18:13:20      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:code   hid   png   return   org   cstring   需要   tin   pos   

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 贪心

标签:code   hid   png   return   org   cstring   需要   tin   pos   

原文地址:https://www.cnblogs.com/Bw98blogs/p/8442184.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!