1100 - Again Array Queries
-> Link <-
又是这种区间查询最值问题,题目意思是要使得这个区间的两个数的差值最小值,上次那个题用的线段树和RMQ水过,不过这题如果要求出区间最值还没什么问题,不过却要求差值最小值,这用RMQ或线段树可怎么做,于是,,,,,,于是,,,,,上网找了找思路,原来还真不是什么线段树、RMQ,而是一个简单的暴力就可以了, 我的天,这要是用前面所提的算法做也就直接陷坑里了;
暴力思路就不用说了吧,直接全部枚举区间所有差值求出最小值,但有个小知识点在这里,所以写篇博客题一下,我们千万注意题目数据范围,虽然查询次数较多,但输入的数据在1000以内,也就是说,如果查询的区间大于1000,那么必有重复元素,这时最小值直接就是0了(注意题意差值应当为正值,所以0是所有差值最小的),这就是所谓的鸽巢原理,即抽屉原理;什么意思呢,假如一年有10个苹果,有9个箱子,要使得这些苹果都能装进箱子里那么有一个盒子必然至少有两个苹果;再比如,一年365天,有366个人,那么必然有两个人生日是同一天;懂了吧,题目数据范围在1000内,如果查询区间大于1000,那么必然有相同的元素,元素个数可以很多,但元素都在1000以内;
所以这题只要注意区间大小这里就没什么问题,不然,,,果断超时~~~来看简短代码:
const int N=100000+10;
int a[N],v[N];
int main()
{
int t,n,k,i,j;
scanf("%d",&t);
int t1=t;
while(t--)
{
scanf("%d%d",&n,&k);
for(i=0; i<n; i++)
scanf("%d",&a[i]);
printf("Case %d:\n",t1-t);
int x,y;
while(k--)
{
memset(v,0,sizeof(v));
scanf("%d%d",&x,&y);
if(abs(y-x)>1000)//查询区间大于1000则必有相同的元素-----抽屉原理,不用则超时;
{
printf("0\n");
continue;
}
j=0;
for(i=x; i<=y; i++)
v[j++]=a[i];
sort(v,v+j);
int xx=unique(v,v+j)-v;//排序后去重,此函数多次介绍,这里不在赘述;
if(xx!=j)//如果去重后元素个数减小了,说明此区间有相同的元素;
printf("0\n");
else
{
int minn=100000;
for(i=1; i<j; i++)//暴力枚举所有差值,注意已经上面已经排好序了, 所以相邻差值是最小的;
minn=min(minn,v[i]-v[i-1]);
printf("%d\n",minn);
}
}
}
return 0;
}