各位大神们。。。。拜托啦。。。。。

lfh15 2012-07-30 01:42:04
为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置。数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。马路上有一些区域要用来建地铁,这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

 

输入描述

输入的第一行有两个整数L(1 ≤ L ≤ 10000)和M(1 ≤ M ≤ 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出描述

输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例输入

500 3
150 300
100 200
470 471
样例输出

298
...全文
200 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2012-08-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

我看代码似乎是O(L)的,难道是我没能理解代码的精妙之处?(最近的弄错的次数也是不少)

[/Quote]
确实就是O(L)与O(m*log(m))的区别
绿色夹克衫 2012-08-01
  • 打赏
  • 举报
回复
我看代码似乎是O(L)的,难道是我没能理解代码的精妙之处?(最近的弄错的次数也是不少)

[Quote=引用 13 楼 的回复:]

引用 9 楼 的回复:

这个问题应该可以做到m * log(m),对区域按照起点排个序,用O(m)遍历一下,把区域合并一下,第二遍遍历一下,统计有多少棵树。

不是可以做到O(mlgm),是可以做到O(m),>_<
[/Quote]
asyuae 2012-07-31
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
int a[10000],b[101];

void kuaipai(int*b,int q,int p){
if(q>=p )
return ;
int i=q,j=q,r=b[p];
while( j<p ){
if(b[j]<b[p] )
swap(b[i++],b[j]);
j++;
}
swap(b[p],b[i]);
kuaipai(b,q,i-1);
kuaipai(b,i+1,p);
}
int main(){
int l,m,n;
cin>>l>>m;
for( int i=0;i<m;i++) {cin>>b[i];cin>>a[b[i]];}
kuaipai(b,0,m-1);
n=0;
for(int i=0 ;b[i];i++ ){
int k=b[i];
while(a[b[i]]>b[i+1]&&b[i+1] )
i++;
n+=( a[b[i]]-k) ;
}
cout<<l-n-1<<endl;
}

T(n)=m*lg(m)
asyuae 2012-07-31
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
int a[10000],b[101];

void kuaipai(int*b,int q,int p){
if(q>=p )
return ;
int i=q,j=q,r=b[p];
while( j<p ){
if(b[j]<b[p] )
swap(b[i++],b[j]);
j++;
}
swap(b[p],b[i]);
kuaipai(b,q,i-1);
kuaipai(b,i+1,p);
}
int main(){
int l,m,n;
cin>>l>>m;
for( int i=0;i<m;i++) {cin>>b[i];cin>>a[b[i]];}
kuaipai(b,0,m-1);
n=0;
for(int i=0 ;b[i];i++ ){
int k=b[i];
while(a[b[i]]>b[i+1]&&b[i+1] )
i++;
n+=( a[b[i]]-k) ;
}
cout<<l-n-1<<endl;
}

T(n)=m*lg(m)
I'm Daniel Du 2012-07-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

这个问题应该可以做到m * log(m),对区域按照起点排个序,用O(m)遍历一下,把区域合并一下,第二遍遍历一下,统计有多少棵树。
[/Quote]
不是可以做到O(mlgm),是可以做到O(m),>_<
绿色夹克衫 2012-07-30
  • 打赏
  • 举报
回复
这个问题应该可以做到m * log(m),对区域按照起点排个序,用O(m)遍历一下,把区域合并一下,第二遍遍历一下,统计有多少棵树。
I'm Daniel Du 2012-07-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

本人一初学者。。。主要是看不懂。。。
[/Quote]
厄,在区间的左端点处记录它的右端点,接着遍历,当遍历到某个点发现line[i]!=0时,说明这里肯定都被删了,然后我们就用flag指出现在这里木有树了,还要再用rp=max(rp,line[i])看看是否有个交集......如果i超过了rp,说明这里肯定有树啦,哈哈,flag=1,继续加啊...然后就,没了T_T.
lfh15 2012-07-30
  • 打赏
  • 举报
回复
本人一初学者。。。主要是看不懂。。。
I'm Daniel Du 2012-07-30
  • 打赏
  • 举报
回复
其实这道题目的范围直接模拟就可以了...
z1572597793 2012-07-30
  • 打赏
  • 举报
回复
...... 有木有高手啊 求给力啊O(∩_∩)O哈哈~
lfh15 2012-07-30
  • 打赏
  • 举报
回复
给分啦~ ~ ~给分啦~ ~ ~有正确代码的给满分
  • 打赏
  • 举报
回复
good,我还以为要用线段树结构,结果这么简单的代码就搞定了。

[Quote=引用 1 楼 的回复:]

C/C++ code

#include<iostream>
using namespace std;

int ans,L,M,line[10001];
int main()
{
cin>>L>>M;int l,r,rp=-1,flag=1;
//rp is right point of a interval,we use rp to maintain a union……
[/Quote]
lfh15 2012-07-30
  • 打赏
  • 举报
回复
有真代码,有真 真相,给力啊
I'm Daniel Du 2012-07-30
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;

int ans,L,M,line[10001];
int main()
{
cin>>L>>M;int l,r,rp=-1,flag=1;
//rp is right point of a interval,we use rp to maintain a union set of all intervals.
for(int i=1;i<=M;i++){
cin>>l>>r;
line[l]=r;
}//input data.
for(int i=0;i<=L;i++){
if(line[i]){
flag=0;
rp=max(line[i],rp);
}
if(i>rp)flag=1;
if(flag)ans++;
}//maintained rp and calculated answer.
cout<<ans<<endl;
return 0;
}

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧