题目描述:
自从诺莫瑞根陷落以后,侏儒们一直寄居在铁炉堡中。大机械师卡斯派普花了不少钱来悬赏勇士们去诺莫瑞根替他取回一些卡片,现在他已经有了一大堆彩色穿孔卡片。但是这些卡片都是残缺不全的,有的甚至还是无效的,想从这些破烂中恢复数据,实在是一件不容易的事。卡斯派普发现每个卡片的开头和结尾都有标记,记录着它原本在矩阵打孔计算机中序列的位置,于是想出了一个恢复数据的方法。把每张卡片看成数轴上的一条线段,开头和结尾的标记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;
}