HDU 1199 Color the Ball(线段切割 离散化思想)

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

这个题目开始一看就知道用线段树加离散化来解,可是好长时间没写线段树了,一时间不知道离散化用线段树怎么搞定

于是就用一个网上称是切割线段的类似模拟方法,感觉这个方法比较容易想,但是写的过程中每一步到底是加一还是减

一都要想好,表示很烦人,开始写的时候其实也挺矛盾,分析下复杂度如果专门挑那些奇怪的测试数据可能会超时,还

是写出来了,果然不出所料wa了几次,但是后来46ms通过可能是数据的问题吧,至于离散化思想我倒是觉得没怎么体

现,反正写出来的代码感觉很恶心了!


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 2500
struct point
{
    int l;
    int r;
}po[maxn];
int pos;
int n;
int black(int a,int b)
{
    int p=pos;
    for(int i=0;i<p;i++)
    {
       if(a>po[i].r || b<po[i].l)
       continue;
       if(a<=po[i].l && b>=po[i].r)
       po[i].l=0,po[i].r=-1;
       else if(a>po[i].l && b<po[i].r)
       po[pos].l=b+1,po[pos].r=po[i].r,po[i].r=a-1,pos++;
       else if(a<=po[i].l && b<po[i].r)
       po[i].l=b+1;
       else if(a>po[i].l && b>=po[i].r)
       po[i].r=a-1;
    }
    return 0;
}
bool cmp(const point &a,const point &b)
{
    if(a.l==b.l)
    return a.r < b.r;
    return a.l < b.l;
}
int main()
{
    int i,j,k,a,b;
    char ch;
    int ans,left,now,my_pos,re_pos;
    while(scanf("%d",&n)!=EOF)
    {
        ans=0;
        pos=0;
        left=0;
        for(i=0;i<n;i++)
        {
        scanf("%d%d",&a,&b);
        getchar();
        scanf("%c",&ch);
        if(ch=='w')
        {
            po[pos].l=a;
            po[pos].r=b;
            pos++;
        }
        else
        {
            black(a,b);
        }
        }
        sort(po,po+pos,cmp);
        //for(i=0;i<pos;i++)
        //printf("%d %d \n",po[i].l,po[i].r);
        if(pos==0)
        {
            printf("Oh, my god\n");
            continue;
        }
        i=0;
        while(po[i].r==-1)
        i++;
        if(i<pos)
        {
        now=po[i].r-po[i].l+1;
        left=po[i].r;
        my_pos=left;
        }
        else
        ans=0,now=0;
        for(i;i<pos;i++)
        {
            if(po[i].l <= left+1)
            {
                if(po[i].r <= left)
                continue;
                else
                now+=po[i].r-left,my_pos=po[i].r,left=po[i].r;
            }
            else
            {
                if(ans < now)
                ans=now,re_pos=my_pos;
                now=po[i].r-po[i].l+1;
                my_pos=po[i].r,left=po[i].r;
            }
        }
         if(ans < now)
            ans=now,re_pos=my_pos;
        if(ans==0)
        {
            printf("Oh, my god\n");
            continue;
        }
        printf("%d %d\n",re_pos-ans+1,re_pos);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值