时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:430
解决:76
-
题目描述:
-
众所周知JOBDU旗下的JOBCOLA公司是文明全球的著名可乐制造商,与其它可乐公司不同的是,JOBCOLA可乐公司并不是以其可乐的味道闻名,而是以其不同寻常的包装瓶被消费者所津津乐道。在JOBCOLA可乐公司成立100周年的日子里,公司搜集了历年来生产的可乐瓶,想通过举办一个可乐瓶展览,以此来提高公司的文化品位。但是受制于展览场地的大小,只能展出一部分的瓶子。经过JOBDU董事会与展览承办商协商之后,决定选出一个连续时期的瓶子用于展览,同时为了达到最佳的美学感受,在所展览的瓶子中,最高的瓶子和最低的瓶子之间的高度,不能超过k。给你的任务就是,挑选出满足上述要求的最长瓶子序列,供董事会选择。
-
输入:
-
每个测试案例包括两行:第一行为两个整数,n和k,其中n代表待选的瓶子个数,k为所选出的瓶子中最高瓶子和最低瓶子之间的最大落差。其中1 <= n <= 10 5, 0 <= k <= 10 6。第二行包含n个整数,每个整数代表瓶子的高度(单位为微米),已知所有瓶子都已经按照生产年代,从古到今进行了排序。
-
输出:
- 对应每个测试案例,输出的第一行包括两个整数a, b。其中a代表满足条件的瓶子个数;b则代表有多少组这样的选择方案。接下来再输出b行,每行包括两个整数s, e (1 <=s,e <=n),其中s代表所选的a个瓶子中最古老的瓶子的下标,而e则代表该方案中最近生产的瓶子下标。注意:若有多个方案,则按照s从小到大的顺序输出;若s相同,则按照e的大小输出。
-
样例输入:
-
3 2 13 12 10
-
样例输出:
-
2 2 1 2 2 3
思路:
其实我没AC,思路还是有问题。以后找时间再AC。先贴别人的代码。
代码:
//ac code
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int height[100009];
int n, k;
int h[100009][20];
int l[100009][20];
int exp2(unsigned x);
int getmax(int x, int y);
int getmin(int x, int y);
int Ok(int len);
int rx[100000];
int ry[100000];
int main(){
while(cin>>n>>k){
for(int i= 0; i< n; ++i){
scanf("%d", height+i);
}
for(int i= 0; i< n; ++i){
h[i][0]= i;
l[i][0]= i;
}
int x= exp2(n);
//RMQ
for(int j= 1; j<= x; ++j){
for(int i= 0; i<= n-(1<<j); ++i){
h[i][j]= h[i][j-1];
l[i][j]= l[i][j-1];
if(height[h[i][j]]< height[h[i+(1<<(j-1))][j-1]]){
h[i][j]= h[i+(1<<(j-1))][j-1];
}
if(height[l[i][j]]>= height[l[i+(1<<(j-1))][j-1]]){
l[i][j]= l[i+(1<<(j-1))][j-1];
}
}
}
int low= 1, high= n;
int mid;
//binary search最大值
while(low< high){
mid= (low+high)>>1;
if(Ok(mid)){
low= mid+1;
}else{
high= mid-1;
}
}
while(!Ok(low))
--low;
int a, b;
int count= 0;
for(int i= 0; i<= n-low; ++i){
a= getmax(i, i+low-1);
b= getmin(i, i+low-1);
if((height[a]-height[b])<= k){
rx[count]=i;
ry[count]=i+low-1;
++count;
}
}
cout<<low<<' '<<count<<endl;
for(int i= 0; i< count; ++i){
cout<<rx[i]+1<<' '<<ry[i]+1<<endl;
}
}
}
int exp2(unsigned x){
int re= 0;
while(x){
x>>=1;
++re;
}
return re-1;
}
int getmax(int x, int y){
int p= exp2(y-x+1);
if(height[h[x][p]]>= height[h[y-(1<<p)+1][p]]){
return h[x][p];
}else{
return h[y-(1<<p)+1][p];
}
}
int getmin(int x, int y){
int p= exp2(y-x+1);
if(height[l[x][p]]< height[l[y-(1<<p)+1][p]]){
return l[x][p];
}else{
return l[y-(1<<p)+1][p];
}
}
int Ok(int len){
for(int i= 0; i<= n-len; ++i){
if(height[getmax(i,i+len-1)]-height[getmin(i,i+len-1)]<= k){
return true;
}
}
return false;
}