百度之星程序设计大赛试题 -2
第二题(共四题 100 分):重叠区间大小( 20 分)
题目描述:请编写程序,找出下面 “ 输入数据及格式 ” 中所描述的输入数据文件中最大重叠区间的大小。
对一个正整数 n ,如果 n 在数据文件中某行的两个正整数(假设为 A 和 B )之间,即 A<=n<=B 或 A>=n>=B ,则 n 属于该行;如果 n 同时属于行 i 和 j ,则 i 和 j 有重叠区间;重叠区间的大小是同时属于行 i 和 j 的整数个数。
例如,行( 10 20 )和( 12 25 )的重叠区间为 [12 20] ,其大小为 9 ;行( 20 10 )和( 12 18 )的重叠区间为 [10 12] ,其大小为 3 ;行 (20 10) 和( 20 30 )的重叠区间大小为 1 。
输入数据:程序读入已被命名为 input.txt 的输入数据文本文件,该文件的行数在 1 到 1,000,000 之间,每行有用一个空格分隔的 2 个正整数,这 2 个正整数的大小次序随机,每个数都在 1 和 2^32-1 之间。(为便于调试,您可下载测试 input.txt 文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出 0 。
评分标准:程序输出结果必须正确,内存使用必须不超过 256MB ,程序的执行时间越快越好。
my answer:
吸取了上一题的教训,知道输入数据的方式是多样的。
int还是不行,要用long long 或者unsigned int
按起点从小到大排序,记录从第一个数据到当前数据为止end最大的位置
刚开始想了很多,区间覆盖就想到了树状数组,后来发现解法挺简单的,不知道怎么改进
#include <iostream> #include <algorithm> using namespace std; struct Node { int start; int end; }; Node node[1000005]; bool cmp(Node a, Node b) { return a.start < b.start; } int main() { freopen("input.txt", "r", stdin); int n,m,cnt = 0; while(cin>>n>>m) { if(n > m) { int temp = n; n = m; m = temp; } node[cnt].start = n; node[cnt].end = m; cnt++; } sort(node, node + cnt, cmp); int max = -1,len = node[0].end,i, temp; for(i = 1; i < cnt; i++) { if(node[i].end < len) temp = node[i].end-node[i].start+1; else temp = len-node[i].start+1; if(temp > max) max = temp; if(node[i].end > len) len = node[i].end; } cout<<max<<endl; return 0; }
牛A陈世熹的比赛答题源码:
跟我的思路差不多,使用STL可能速度会快一点
#include <iostream> #include <cstdio> #include <utility> #include <algorithm> using namespace std; struct pair_less { bool operator()(const pair<int, int>& A, const pair<int, int>& B) const { return A.first < B.first; } }; int N; pair<int, int> List[2000000]; int MaxResult; int main() { int I, J, Last, A, B; freopen("input.txt", "r", stdin); N = 0; while (scanf("%d%d", &A, &B) > 0) { if (A > B) I = A, A = B, B = I; List[N] = make_pair(A, B); N++; } sort(List, List + N, pair_less()); Last = 0x80000000; MaxResult = 0; for (I = 0; I < N; I++) { if (List[I].first <= Last) { if (List[I].second <= Last) J = List[I].second - List[I].first + 1; else J = Last - List[I].first + 1; if (J > MaxResult) MaxResult = J; } if (List[I].second > Last) Last = List[I].second; } printf("%d\n", MaxResult); return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> //buf const int bufsize=128*1024; int bufL,bufP; char buf[bufsize]; //segments const int maxn=1000005; int n; unsigned int A[maxn],B[maxn]; //sort const int countsize=65536; int arcA[maxn],arcB[maxn],turnB[maxn]; int count[countsize],tmp[maxn]; //solve unsigned int maxB[maxn],maxL[maxn]; void swap(unsigned int &a,unsigned int &b) { unsigned int t=a; a=b; b=t; } char readchar() { if (bufL==bufP) { bufL=read(0,buf,bufsize); if (bufL==0) return 0; bufP=0; } return buf[bufP++]; } bool readnumber(unsigned int &v) { char c; do{ c=readchar(); if (c==0) return false; }while (c<'0' || c>'9'); for (v=0;c>='0' && c<='9';c=readchar()) v=v*10+(c-48); return true; } void init() { bufL=bufP=0; for (n=0;readnumber(A[n+1]) && readnumber(B[n+1]);) { n++; if (A[n]>B[n]) swap(A[n],B[n]); } } void count_sort(unsigned int A[],int arc[]) { int i; //lower bit memset(count,0,sizeof(count)); for (i=1;i<=n;i++) count[A[i]&65535]++; for (i=1;i<countsize;i++) count[i]+=count[i-1]; for (i=n;i>=1;i--) tmp[count[A[i]&65535]--]=i; //higher bit memset(count,0,sizeof(count)); for (i=1;i<=n;i++) count[A[i]>>16]++; for (i=1;i<countsize;i++) count[i]+=count[i-1]; for (i=n;i>=1;i--) arc[tmp[i]]=(count[A[tmp[i]]>>16]--); } void preprocess() { count_sort(A,arcA); count_sort(B,arcB); for (int i=1;i<=n;i++) turnB[arcB[i]]=i; } void checkmax(double &answer,unsigned int S,unsigned int T) { if (S>T) return; double t=double(T)-double(S)+1; if (t>answer) answer=t; } #define lowbit(n) (((n)^((n)-1))&(n)) void add_maxB(int i,unsigned int v) { for (;i<=n;i+=lowbit(i)) if (v>maxB[i]) maxB[i]=v; } void add_maxL(int i,unsigned int v) { i=n+1-i; for (;i<=n;i+=lowbit(i)) if (v>maxL[i]) maxL[i]=v; } unsigned int get_maxB(int i) { unsigned int t=0; for (;i>0;i-=lowbit(i)) if (maxB[i]>t) t=maxB[i]; return t; } unsigned int get_maxL(int i) { i=n+1-i; unsigned int t=0; for (;i>0;i-=lowbit(i)) if (maxL[i]>t) t=maxL[i]; return t; } void solve() { double answer=0; memset(maxB,0,sizeof(maxB)); memset(maxL,0,sizeof(maxL)); for (int T=1;T<=n;T++) { int i=turnB[T],LA=arcA[i]; checkmax(answer,A[i],get_maxB(LA)); checkmax(answer,1 ,get_maxL(LA)); add_maxB(LA,B[i]); add_maxL(LA,B[i]-A[i]+1); } printf("%0.0lf\n",answer); } int main() { freopen("input.txt","r",stdin); init(); preprocess(); solve(); return 0; }