一道智商题,说水也行,没有算法,模拟就行,说不水也行,看你用什么方法模拟。
比赛的时候讨论的两个序列有几个元素,当总个数为奇偶的情况再分左右哪边的多,再分多的那边个数的奇偶。。。写了10+次还是不全面。
上网查了大神们的代码解析,他们用的都是讨论区间位置关系。
两个区间只有不相交和相交但是不包含和包含三种关系。
做一下简化处理可以使后两种情况合并为一种,所以只有两种情况。然后确定中位数在这两种情况里面的位置即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=1e5+5;
int l1,r1,l2,r2,sum;
double a[maxn];
double ans(int x)
{
if(r1<=l2)
{
if(x<=r1-l1+1)
return a[l1+x-1];
else
return a[l2+x-1-r1+l1-1];
}
else
{
if(r1>r2)
swap(r1,r2);
if(x<=l2-l1)
return a[l1+x-1];
else if(x>r1-l1+1+r1-l2+1)
return a[l2+x-r1+l1-1-1];
else
return a[l2+(x-l2+l1+1)/2-1];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%lf",&a[i]);
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
if(l1>l2)
{
swap(l1,l2);
swap(r1,r2);
}
sum=r1-l1+1+r2-l2+1;
if(sum%2)
printf("%.1f\n",ans(sum/2+1));
else
printf("%.1f\n",(ans(sum/2)+ans(sum/2+1))/2);
}
}
}
PS:顺便自己检讨很久没补题刷题了。