Zoj 3581 离散化
2011-07-25 15:40
239 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4383
题意很简单:有两根一样长(1000W)的绳子,第一条绳子有n1(10W)个区间的缺陷,第二条绳子有n2(10W)个区间的缺陷,两条绳子粘在一起,求只有一次缺陷的最长区间~
比赛的时候分析直接暴力肯定会超时 O_O,然后觉得肯定要用线段树+离散化,可惜线段树不会写,于是放弃了*_*赛后别人说纯暴力就能过,还不信,特地去写了一下。
直接暴力交了之后是600ms,于是觉得可以离散化。时间是300多。
题意很简单:有两根一样长(1000W)的绳子,第一条绳子有n1(10W)个区间的缺陷,第二条绳子有n2(10W)个区间的缺陷,两条绳子粘在一起,求只有一次缺陷的最长区间~
比赛的时候分析直接暴力肯定会超时 O_O,然后觉得肯定要用线段树+离散化,可惜线段树不会写,于是放弃了*_*赛后别人说纯暴力就能过,还不信,特地去写了一下。
#include<stdio.h> #include<string.h> const int MAXN = 10000001; int flag[MAXN]; int max_len(int n) { int re =0,num; for(int i=0;i<n;) { num = 0; while(flag[i]==1) { num++; i++; } if(num>re) re = num; i++; } return re; } int main() { int n,n1,n2,x,y; while(scanf("%d%d%d",&n,&n1,&n2)!=EOF) { memset(flag,0,sizeof(flag)); int t = n1+n2; for(int i=0;i<t;i++) { scanf("%d%d",&x,&y); for(int j=x;j<=y;j++) flag[j]++; } printf("%d\n",max_len(n)); } return 0; }其实仔细分析了一下,若数据保证输入的区间不会重复的话,赋值+查找最多复杂度也才是3000W,额。。当时傻了。。
直接暴力交了之后是600ms,于是觉得可以离散化。时间是300多。
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; const int maxn=100001; struct node { int x,y; }oo[2*maxn],que[4*maxn]; int tt[4*maxn],flag[4*maxn]; int deal(int n) { int i,re=0; que[re].x = tt[0]; que[re++].y = tt[0]; for(i=1;i<n;i++) { if(tt[i]-tt[i-1]>1) { que[re].x = tt[i-1] + 1; que[re++].y = tt[i] -1; } que[re].x = tt[i]; que[re++].y = tt[i]; } return re; } int search(int val,int len) { int l,r,mid; l = 0; r = len; while(l<=r) { mid = ((l+r)>>1); if(que[mid].x == val) return mid; else if(que[mid].x >val) r = mid - 1; else l = mid + 1; } return -1; } void sum(int a) { int i,re=0,num; for(i=0;i<a;) { num = 0; while(flag[i] == 1) { num += (que[i].y - que[i].x +1); i++; } if(num>re) re = num; i++; } printf("%d\n",re); } int main() { int m,n1,n2,i,num; while(scanf("%d%d%d",&m,&n1,&n2)!=EOF) { int tmp = n1+n2; num=0; for(i=0;i<tmp;i++) { scanf("%d%d",&oo[i].x,&oo[i].y); tt[num++] = oo[i].x; tt[num++] = oo[i].y; } sort(tt,tt+num); int cnt = unique(tt,tt+num)-tt;//tt中不相同点的个数 int a = deal(cnt);//对tt中的点进行坐标离散化后区间个数 memset(flag,false,sizeof(flag)); for(i=0;i<tmp;i++)//赋值 { int l = search(oo[i].x,a); int r = search(oo[i].y,a); for(int j=l;j<=r;j++) flag[j]++; } sum(a);//统计 } return 0; }其实我觉得若是没有那个区间不重复的条件的话,这两种方法应该都会超,队员写了线段树+离散化,一直MLE,可能写搓了,求线段树+离散化!!
相关文章推荐
- ZOJ 3518 Unsafe Factor(离散化)
- 线段树区间更新+离散化——ZOJ 3299
- ZOJ 2301 Color the Ball 线段树(区间更新+离散化)
- ZOJ_3790_Consecutive Blocks(离散化+二分/单调队列)
- zoj 3299 线段树 离散化
- ZOJ 2301 / HDU 1199 Color the Ball 离散化+线段树区间连续最大和
- zoj 3349 Special Subsequence 【离散化二分 + 线段树优化dp】
- ZOJ 3299-Fall the Brick(线段树+离散化)
- ZOJ 3016 Cut(离散化+最小生成树)
- ZOJ 3790 Consecutive Blocks【离散化】【贪心】
- ZOJ 3042 City Selection II 【序】【离散化】【数学】
- ZOJ-3612-树状数组+第k小数+离散化
- ZOJ 3790 Consecutive Blocks (离散化 + 暴力)
- zoj 3299(区间改动+离散化)
- zoj 3581 A Simple Test 模拟题
- zoj 3790 Consecutive Blocks 离散化+二分
- ZOJ 2010 Equipment Box(POJ 1380)(暴力离散化)
- zoj 2301 Color the Ball(区间染色,线段树+离散化)
- Poj 3581 Sequence (离散化+后缀数组)
- ZOJ 3642 多重匹配 离散化.cpp