HDOJ 1050 Moving Tables 【贪心】

HDOJ 1050 Moving Tables 【贪心】

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1050


这个题是根据贪心训练所以写的贪心
但是有一种更简单的求法就是求最大重复区间:
【将走廊分成200块,每次输入后就对涉及到的走廊+1
最后输出这些数组里最大的数*10就可以了】
上面这种写法比较简单,不贴代码了


贪心的话首先是把输入的区间预处理:
1、左区间小于右区间,不符合的话交换一下
2、左边的数据是偶数的话就-1换成奇数
3、右边的数据是奇数的话就+1换成偶数
以上操作是将涉及到的区间扩展到最大边界
然后贪心一直跑
每跑一趟就将可以同时进行的操作标记为vis,同时num++
然后再从头开始将没有访问过的区间标记vis,num++
最后所有的区间都访问过后,输出最后的num*10即可


这个题一开始区间排序是按右区间从小到大,再左区间从小到大排
然而总是wa……
换成先按左区间从小到大排再按右区间从小到大就过了……
反例见下:
1
19
75 154
125 158
176 48
196 65
21 171
15 170
17 100
61 116
3 189
98 104
112 19
163 66
42 14
81 168
53 165
36 143
84 140
105 199
195 151
AC代码结果为150,WA代码结果为160
**按照右房间排序后,右房间的号码一旦大于之后所有的左房间号码,
那么之后的所有区间就是每个区间占用一个新的num
**按照左房间排序,右房间号码过大后,下一个区间右房间依然可能变小,所以每次机会都是均等的,可以进行贪心
所以……要那么排……就素酱紫……


#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef struct point{
    int x, y;
    int vis;
    bool operator < (const point& p) const{
        if(x == p.x) return y < p.y;
        else return x < p.x;
    }
    bool operator > (const point& p) const{
        return p < *this;
    }
}p;
int T, N;
p room[205];
int End, num, cnt;

int main(){
    scanf("%d", &T);
    while(T--){
        scanf("%d", &N);
        for(int i = 0; i < N; i++) scanf("%d%d", &room[i].x, &room[i].y);
        for(int i = 0; i < N; i++){
            room[i].vis = false;
            if(room[i].x > room[i].y) swap(room[i].x, room[i].y);
            if(!(room[i].x & 1)) room[i].x -= 1;
            if(room[i].y & 1) room[i].y += 1;
        }
        sort(room, room+N);
        //for(int i = 0; i < N; i++) printf("%d\t%d\n", room[i].x, room[i].y);
        cnt = 0;
        num = 0;
        while(cnt != N){
            for(int i = 0; i < N; i++){
                if(room[i].vis == 0){
                    End = room[i].y;
                    room[i].vis = true;
                    cnt++;
                    num++;
                    break;
                }
            }
            for(int i = 1; i < N; i++){
                if(room[i].x >= End && room[i].vis == false){
                    End = room[i].y;
                    cnt++;
                    room[i].vis = true;
                }
            }
        }
        printf("%d\n", num*10);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值