您的位置:首页 > 其它

46.贪心算法练习:  区间合并

2016-03-05 13:19 316 查看
总时间限制:

1000ms

内存限制:

65536kB


描述


给定 n

个闭区间 [ai;
bi],其中i=1,2,...,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如,[1;2]

和 [2;3]

可以合并为 [1;3],[1;3]

和 [2;4]

可以合并为 [1;4],但是[1;2]

和 [3;4]

不可以合并。

我们的任务是判断这些区间是否可以最终合并为一个闭区间,如果可以,将这个闭区间输出,否则输出no。


输入


第一行为一个整数n,3
≤ n ≤ 50000。表示输入区间的数量。

之后n行,在第i行上(1
≤ i ≤ n),为两个整数
ai

和 bi

,整数之间用一个空格分隔,表示区间[ai;
bi](其中1
≤ ai ≤ bi ≤ 10000)。


输出


输出一行,如果这些区间最终可以合并为一个闭区间,输出这个闭区间的左右边界,用单个空格隔开;否则输出no。


样例输入


5

5 6

1 5

10 10

6 9

8 10


样例输出


1 10

贪心代码(要用覆盖才可以):

#include

using namespace std;

#include

#include

struct QJ{

int z,y;

};

const int INF=50001;

QJ qj[INF];

int zz=INF,yy=-INF;

int cmp(const QJ &a,const QJ &b)

{

return a.z

}

int main()

{

int n;

cin>>n;

for(int i=1;i<=n;++i)

{

scanf("%d%d",&qj[i].z,&qj[i].y);

if(qj[i].z<=zz)

zz=qj[i].z;

if(qj[i].y>=yy)

yy=qj[i].y;

}

sort(qj+1,qj+n+1,cmp);

for(int i=2;i<=n;++i)

{

if(qj[1].y>=qj[i].z)

{

if(qj[1].z>qj[i].z)

qj[1].z=qj[i].z;

if(qj[1].y

qj[1].y=qj[i].y;

}

if(qj[1].y

{

printf("no\n");

return 0;

}

}

printf("%d %d\n",zz,yy);

return 0;

}

//反例:(1,7)
与(2,3)和(4,5)会判断无法形成闭合区间

//反例
1,2 3,5
2,7 应该输出1,7
,但是这样算法结果是no,这个不同于“线段覆盖那道题”要用最少的线段(用右端点拍,再用左端点判断),这个题要用所有的边,从小判断到大。

错误代码:

#include

using namespace std;

#include

const int maxn=50001;

int visit[maxn]={0};

int zz=maxn,yy=-maxn;

int main()

{

int n;

cin>>n;

for(int i=1;i<=n;++i)

{

int a,b;

scanf("%d%d",&a,&b);

for(int j=a;j<=b;++j)

visit[j]=1;

if(a

zz=a;

if(b>yy)

yy=b;

}

for(int i=zz;i<=yy;++i)

{

if(visit[i]==0)

{

cout<<"no"<<endl;

return 0;

}

}

printf("%d %d",zz,yy);

return 0;

}

反例:应该是存边,而不是存点,因为(1,2),(3,4),2与3之间,没有覆盖,却判断是成立的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: