C- interval coverage (does not support C ++ 11)
One, Title Description
There are a number line n (1 <= n <= 25000) a closed interval [ai, bi], selected to cover a range of as little as specified segment [1, t] (1 < = t <= 1,000,000).
Covering the entire point, i.e., (1,2) + (3,4) may cover (1,4).
The impossible Output -1
Entry
第一行:N和T
第二行至N+1行: 每一行一个闭区间。
Export
选择的区间的数目,不可能办到输出-1
Sample input
3 10
1 7
3 6
6 10
Sample Output
2
prompt
这道题输入数据很多,请用scanf而不是cin
Second, ideas and algorithms
The minimum number of sections required to cover a certain period interval, this algorithm is the main problem, first of all sorted interval (interval to a first point of the left ascending keywords to the right end of the second section ascending keyword), then [1 , t] both sides of the cut section.
Thereafter, as the core: each of a selected interval, the cover portion has been cut off are, in the cover section can continue down, the selected maximum interval until [1, t] are covered completed.
Must pay attention to are: an integer coverage requirements, so there are requirements +1.
2. Select a starting point of the first interval must be 1, otherwise the sentence is impossible.
3. The key may exceed t, e.g. [1,12] Cover [1,10]
Third, code implementation
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct period{
int a,b;
period(){}
period(int aa,int bb){a=aa; b=bb;}
bool operator <(const period &p)const{ //重载<
if(a!=p.a){return a<p.a;}
else{return b<p.b;}
}
};
int main(){
int N,T;
vector<period> all(0);
int ta,tb;
//读入所有区间
scanf("%d %d",&N,&T);
for(int i=0;i<N;i++){
scanf("%d %d",&ta,&tb);
all.push_back(period(ta,tb));
}
sort(all.begin(),all.end());
int s=all.size();
//切掉[1,T]以外的部分
while(all.empty()==0&&all[s-1].a>T){
all.pop_back();
s--;
}
while(all.empty()==0&&all[0].a<1){
vector<period>::iterator it=all.begin();
all.erase(it);
s--;
}
//开始选择区间
if(all.empty()==1){printf("-1\n"); return 0;}
int result=0; //需要的区间总数
if(all[0].a>1){printf("-1\n"); return 0;}
int tmp=0,j=0;
int latest=1,flag=0;
while(latest<T)
{
int maxlen=0; //目前长度最长区间长度
if(flag==0){ //flag只在第一次为0,处理第一个区间
flag=1;
for(int i=0;(all[i].a==1)&&i<all.size();i++){
tmp=all[i].b-1;
if(maxlen<tmp){maxlen=tmp; j=i;}
}
if(maxlen==0) {printf("-1\n"); return 0;}
result++; latest=all[j].b;
}
else{
for(int i=0;(i<all.size())&&(all[i].a<=(latest+1));i++)//找当前左边界最长
{ if(all[i].b>latest){
tmp=all[i].b-latest;
if(tmp>maxlen)
{
maxlen=tmp;
j=i;
}
}
}
if(maxlen==0) {printf("-1\n"); return 0;}//不存在覆盖
else{
result++;
latest=all[j].b;
}
}
}
printf("%d\n",result);
return 0;
}
Fourth, experience and summary
- Remember Remember! ! Heavy load <Be sure to include all cases! What returns are not equal when, what time and equal return, or will WA!
- Time uncertain cycle boundary and other data, you can use test data, tracking data operation to determine the boundaries set correctly, how mistaken the change.
- scanf time performance is better than cin, more recommended scanf, printf.
- Greedy index is the most important part of the greedy algorithm, the correctness of the greedy algorithm dependent on the correctness of indicators, so greedy indicators must be carefully chosen!