原题目
Description

 

N个人做一个游戏,游戏中每个人说了一句话(可能是真的也可能是假的)
第i个人说:“N个人中有至少有ai个,至多有bi个人说的是真话!”(i = 1, 2, 3…..N)你能推断出最多能有多少个人说的是真话吗?
1 <= N <= 100000;
0 <= ai<=bi<=1000000000;

 

Input

 

第一行为一个整数T,代表测试数据的组数;
每组数据以n开头,接下来有n行,每行两个整数ai,bi(代表第i个人说的);

 

Output

 

输出占一行。如果原问题有解,输出最多能有多少个人说的是真话;否则输出-1.

 

Sample Input

 

2
3
0 0
1 1
2 2
3
2 5
3 5
0 3

 

Sample Output

 

1
3

分析
        题目什么意思呢?
        总共N个人,那说真话最多只有N个人,为什么ai和bi的值可以远大于N呢?结合示例不难得知,原来ai和bi的值只是给个说真话的人数的范围,说真话的人数自然是在N以内的。假如某人可能说真话,则其给出的区间必然包含1至N的某值,因此说出区间[0,0]的那家伙肯定说假话;如果给出的区间左端值ai>N,那么他也肯定说假话。因此,判断可能说真话的最多人数时,可以不考虑这些必然说假话的人。假如最多X个人全部说真话(当然其余N-X说假话了),那么X必然在他们给出的交集区间[ax,bx]中。
      于是,本题的意思就是寻找最大的X满足:X属于[ax,bx],其中[ax,bx]表示X个人给出的交集区间。
         那如何才能得到呢?对任意一个给出的区间[ai,bi],他能结合的可能其他人数是有限的,不妨设为Xi,Xi的最大值取决于区间的右端值。N个人中,可能有些部分之间没有交集,应该单独考虑这些部分,最后再比较。对于有交集的部分,可以证明只有按照Xi有序进行结合,才能得到最大的X。结合所能给出的可能全部说真话的人数取决于他们当中最小的Xi,不妨设X1<X2<X3(逆序等效),则X1和X2结合、X1和X3结合均取决于X1。如果X1、X2、X3能全部结合,即X1+X2+X3在他们的交集区间中,那么与顺序无关,但是倘若只有部分能结合,则显然能结合的部分的最小Xi同较小Xk结合,使得剩下的Xj较大,则可能使Xj同其他结合得到更大值。因此,可以按照给出区间的右端值进行排序,然后再逐个结合判断。
        判断的大致过程:若有交集并且结合后的X值不大于交集右端值(可能也小于左端值,因为结合尚未完成),则结合;否则表示这部分结合完毕,可以判断是否可能是符合题意的X,即X是否在交集区间中,若是则记录以便同其他部分比较,否则继续另一部分的结合。最后比较各部分得到最大的X值即为所求。

解答
        我提交了好几次,推测出成电OJ的测试数据已经是排好序的了,因此解题代码中就不考虑排序了。实际上,我写了排序后,测了几组数据没问题,而AC的代码(即未排序的)测未排序的数据会出错。提交排序的后,结果run time error,原来不允许调用qsort快排例程。

附录
       下面是我的AC代码。这个代码的时间39ms、空间852KB,在该题Best Solution中排第九,而且所占空间是最小的。但是代码长度略长,后来去掉join函数简化到约50行,可是结果却没这个好。最后本人能力实在有限,不对之处恳请指正,不胜感激。

真实的谎言 (1003 )

User: xuebao2013 Result: AcceptedDate: 2013-10-10 03:07:55

  1. #include<stdio.h>
  2. bool join(int *AB,int A,int B)
  3. {
  4. int a=AB[0],b=AB[1];
  5. if(B<a||A>b)return false;
  6. if(B<b)b=B;
  7. if(A>a)a=A;
  8. if(AB[2]+1>b)return false;
  9. AB[0]=a;
  10. AB[1]=b;
  11. AB[2]++;
  12. return true;
  13. }
  14. int main()
  15. {
  16. int T;
  17. scanf("%d",&T);
  18. int AB[3],N,A,B,maxcount;
  19. int i,j;
  20. for(i=0;i<T;i++)
  21. {
  22. AB[0]=AB[1]=0;
  23. AB[2]=-1;
  24. scanf("%d",&N);
  25. maxcount=0;
  26. for(j=0;j<N;j++)
  27. {
  28. scanf("%d%d",&A,&B);
  29. if(B<1||A>N)continue;
  30. if(AB[2]==-1)
  31. {
  32. AB[0]=A;AB[1]=B;
  33. AB[2]=1;
  34. continue;
  35. }
  36. if(join(AB,A,B))continue;
  37. if(AB[2]>=AB[0])
  38. if(AB[2]>maxcount)
  39. maxcount=AB[2];
  40. AB[0]=A;AB[1]=B;
  41. AB[2]=1;
  42. }
  43. if(AB[2]>=AB[0])
  44. if(AB[2]>maxcount)
  45. maxcount=AB[2];
  46. if(maxcount>0)printf("%d\n",maxcount);
  47. else printf("-1\n");
  48. }
  49. return 0;
  50. }

[置顶] 解成电OJ1003真实的谎言的记录的更多相关文章

  1. ahk之路:利用ahk在window7下实现窗口置顶

    操作系统:win7 64位 ahk版本:autohotkey_L1.1.24.03 今天安装了AutoHotkey_1.1.24.03.SciTE.PuloversMacroCreator,重新开始我 ...

  2. DataGridView控件绑定数据之后,置顶操作

    一个小小的置顶,就搞了半个小时,还是记录一下吧. 1.第一个问题就是datatable的插入只能是Insert DataRow,但是获取选中的行,都是DataGridViewRow,不能直接转换. 找 ...

  3. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  4. C#或者WPF中让某个窗体置顶

    原文:C#或者WPF中让某个窗体置顶 前记:在工作中有个需求,要求不管到那个界面,我必须让一个浮动条(其实是个窗体)置顶. 我用wpf,因为有之前有好几个界面已经设置成topmost了,所以在这几个界 ...

  5. js之滚动置顶效果

    0.js获取高度 ? 1 2 3 4 5 6 document.all   // 只有ie认识   document.body.clientHeight              // 文档的高,屏幕 ...

  6. 【搬运工】NOIP吧置顶贴

    目的是存置顶贴里的链接.. 原帖:http://tieba.baidu.com/p/1753284199 资源站:*C++资源:http://tieba.baidu.com/p/1239792581* ...

  7. android linearlayout imageview置顶摆放

    在练习android时,想在Linearlayout内放一图片,使其图片置顶,预期效果是这样的: 但xml代码imageview写成这样后, <ImageView android:layout_ ...

  8. QT窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透

    qt 窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透 窗口置顶qt 里是 setWindowFlags(Qt::WindowStaysOnTopHint)kde 里 ...

  9. [知了堂学习笔记]_css3特效第二篇--行走的线条&&置顶导航栏

    一.行走的线条. 效果图(加载可能会慢一点儿,请稍等...): html代码: <div class="movingLines"> <img src=" ...

随机推荐

  1. Java泛型:类型擦除

    类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...

  2. C#基础精华06(Linq To XML,读取xml文件,写入xml)

    1.XML概述: 可扩展标记语言XML(eXtensible Markup Language)是一种简单灵活的文本格式的可扩展标记语言,侧重于存储数据. 2.XML特点 xml 标记语言 html x ...

  3. 再探Tomcat

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAmQAAADyCAIAAABs006cAAAgAElEQVR4nO2d228b1RaH+2/l9RQhQE

  4. 对Cost (%CPU) 粗略的理解

    今天研究执行计划,看到执行计划里面有Cost (%CPU),我这边研究了一把,不知道对与否,拿出来晒晒 在Oracle 10g中,Oracle 把CPU的cost也统计在执行计划中去了, 这和以前的8 ...

  5. WCF实例上下文

    实例上下文模式(IntanceContext Mode)表示服务端的服务实例与客户端的服务代理的绑定方式. 在WCF中有三种不同的实例上下文模式,单调(Per-Call)模式,会话(Per-Sessi ...

  6. java事务管理(二)

    数据库事务和Spring事务是一般面试都会被提到,很多朋友写惯了代码,很少花时间去整理归纳这些东西,结果本来会的东西,居然吞吞吐吐答不上来. 下面是我收集到一些关于Spring事务的问题,希望能帮助大 ...

  7. HTML5学习(四)---Canvas绘图

    参考教程地址:http://www.w3school.com.cn/html5/html_5_canvas.asp canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 c ...

  8. Linux命令行批量替换多文件中的字符串【转】

    Linux命令行批量替换多文件中的字符串[转自百度文库] 一种是Mahuinan法,一种是Sumly法,一种是30T法分别如下: 一.Mahuinan法: 用sed命令可以批量替换多个文件中的字符串. ...

  9. 2013 ACM/ICPC Asia Regional Changsha Online - G(DP)

    第一眼就想到DP,然后想了N久就想不到可以不重算的DP  最后没办法了 先算出来 再去重.. 因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都 ...

  10. poj 水题系列

    题目:http://poj.org/problem?id=3006 筛选法求素数 #include <iostream> #include<cstdio> #include&l ...