浮水法

题目描述:

自从诺莫瑞根陷落以后,侏儒们一直寄居在铁炉堡中。大机械师卡斯派普花了不少钱来悬赏勇士们去诺莫瑞根替他取回一些卡片,现在他已经有了一大堆彩色穿孔卡片。但是这些卡片都是残缺不全的,有的甚至还是无效的,想从这些破烂中恢复数据,实在是一件不容易的事。卡斯派普发现每个卡片的开头和结尾都有标记,记录着它原本在矩阵打孔计算机中序列的位置,于是想出了一个恢复数据的方法。把每张卡片看成数轴上的一条线段,开头和结尾的标记A,B为数轴上的两个点。卡斯派普按拿到的顺序把卡片一张一张地贴到数轴上,每张卡片的颜色都不同。他想知道贴完卡片以后的数轴上一共有多少种不同的颜色。卡斯派普请你帮助他写一个程序来解决这个问题。

l 第1行:一个整数N,表示卡斯派普收集到的卡片的数量。

l 第2行至第N+1行:第i+1行给出了第i张卡片的头尾两个标记Ai,Bi,贴卡片的顺序与输入文件中出现的先后顺序一致。

 

输出格式

l 一个整数,表示卡斯派普能在数轴上看到的不同的颜色的数目。

 

样例输入

4

0 5

3 8

5 6

4 7

 

样例输出

3

50%的数据满足N<=1,000; 0<=Ai<Bi<=100,000(1<=i<=N);

100%的数据满足N<=20,000; 0<=Ai<Bi<=1,000,000,000(1<=i<=N)。


这道题用浮水法最好解决,浮水法,起的很形象很生动啊。


#include <cstdio>
#include <cstdlib>
#include <cstring>
struct
{
       int l,r;
}e[1000000];
bool v[100000];
int i,n,ans;
void make(int a,int b,int q)
{
     if (v[i]==true) return;
     while (q<=n&&(a>=e[q].r||b<=e[q].l)) q++;
     if (q>n) 
     {
              ans++;
              v[i]=true;
     }
     if (e[q].l>a&&e[q].l<b) make(a,e[q].l,q+1);
     if (e[q].r>a&&e[q].r<b) make(e[q].r,b,q+1);
}
int main()
{
    freopen("punch.in","r",stdin);
    freopen("punch.out","w",stdout);
    scanf("%d",&n);
    for (i=1;i<=n;i++)
      scanf("%d%d",&e[i].l,&e[i].r);
    memset(v,0,sizeof(v));  
    for (i=n-1;i>0;i--)
    {
        make(e[i].l,e[i].r,i+1);
    }
    printf("%d",++ans);
    return 0;
}  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值