[分治] 区间合并

总时间限制: 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。


【题目分析】
一道有陷阱的水题。首先,定义一个数组a,用样例分析一下,可以很快得出做法:先将a清零,然后把a[1]~a[2]放1,把a[2]~a[3]放1,取[1;2][2;3]的最大最小值max=3,min=1,for(i=min;i<=max;i++)看a[i]是不是1就行了。
但是并不是AC的。题目描述中说[1;2][3;4]并不能合并,这又是为什么呢?
通过一个数轴,我们可以简单理解一下:1~2是一条线段,3~4是一条线段,2~3并没有用线段连接,所以不能合并为一个区间。如果你用如上做法,程序会判断它为一个可合并的区间,故答案错误。
那应该用什么方法呢?没关系,只要你将max,min放大一倍就行了(for(i=min*2;i<=max*2;i++))。这样就巧妙避免了这种情况,也并不影响答案。不信你可以单步调试一下哟。


下面附上此题AC代码。
#include<cstdio>
#include<iostream>
using namespace std;
int a[20001];
int main()
{
    int n,max=0,min=214736478,b,c;
    ios::sync_with_stdio(false);//取消与stdio的同步流,优化cin,cout速度,使其与scanf,printf速度相当
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>b>>c;
        if(b<min)min=b;
        if(c>max)max=c;
        for(int j=b*2;j<=c*2;j++)a[j]=1;
    }
    for(int i=min*2;i<=max*2;i++)
    {
        if(!a[i])
        {
            cout<<"no";
            return 0;
        }
    }
    cout<<min<<‘ ‘<<max;
    return 0;
}
时间: 2024-10-29 00:36:31

[分治] 区间合并的相关文章

7620:区间合并

7620:区间合并 总时间限制: 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 ≤ 5000

HDU 3911 Black And White(线段树区间合并)

Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she wan

(树链剖分+区间合并)HYSBZ - 2243 染色

题意: 两个操作: 1.把一条树链上的所有点权值变为w. 2.查询一条树链上有多少个颜色段 分析: 一看就是区间合并,做这到题首先需要一定的区间合并基础, 不过这题合并这部分在线段树区间合并中已经算是非常的简单的了. 线段树部分没有难度. 那么难点在于,在往LCA上走的时候,我们如何进行区间合并. 本来我想着, 在向上走的时候顺便进行区间判断并且合并,但是似乎有问题. 其实,可以将两步分开,先算出区间没合并之前的颜色段数,再次进行Top,判断颜色是否相等,相等就减掉. 代码: 1 #includ

poj3667(并查集区间合并&amp;区间查询)

题目链接: http://poj.org/problem?id=3667 题意:第一行输入 n, m表示有 n 间房间(连成一排的), 接下来有 m 行输入, 对于接下来的 m 行输入: 1 x : 询问是否有长度为 x 的连号空房, 若有, 住进最左边并输出对应编号: 2 x y : 将区间 [x, x + y - 1] 的房间清空: 思路: 并查集区间合并&区间查询 下面一段题解摘自: http://www.cnblogs.com/scau20110726/archive/2013/05/0

HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并

Tunnel Warfare                                  Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast

HDU 3308 LCIS (线段树区间合并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[mid + 1] > a[mid],写的细心点就好了. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int MAXN = 1

HDU 2871 Memory Control(线段树&#183;区间合并&#183;Vector)

题意  模拟内存申请  有n个内存单元  有以下4种操作 Reset  将n个内存单元全部清空 New x  申请一个长度为x的连续内存块  申请成功就输出左端 Free x  将x所在的内存块空间释放  释放成功输出释放的内存始末位置 Get x  输出第x个内存块的起始位置 Reset 和 New 都是基本的区间合并知识  比较简单  Free和Get需要知道内层块的位置  所以我们在New的时候要将申请的内存块的始末位置都存起来  两个内层块不会相交  这样就能通过二分找到需要的内层块了

HDU 3397 Sequence operation(区间合并 + 区间更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给定n个数,由0,1构成.共有5种操作.每个操作输入3个数,op,a,b. op == 0,将区间[a,b]赋值为0: op == 1,将区间[a,b]赋值为1: op == 2,将区间[a,b]内的01反转: op == 3,查询区间[a,b]中1的个数: op == 4,查询区间[a,b]中连续1的最大长度: 思路:区间合并 + 区间更新.每个结点存7个数: 区间内1的个数c1. 从

HDU 5316 Magician(线段树区间合并, 子序列最值 多校2015啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316 Problem Description Fantasy magicians usually gain their ability through one of three usual methods: possessing it as an innate talent, gaining it through study and practice, or receiving it from an