题解:P6332 [COCI 2007/2008 #1] PRINOVA
题目
题意
给定长度为
输出任意一个满足条件的
思路
我们观察到,要使
- 某两个相邻偶数的正中间附近;
- 或者靠近区间
\left [ A,B \right ] 的边界。
我们只要把这些候选奇数都找出来,逐一计算它们到所有偶数的距离的最小值,记录下最优解即可。
代码如下
#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
int n,p[MAXN],A,B;
vector<int> cand;//用来收集候选奇数
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(int i=0;i<n;i++){
cin>>p[i];
}
cin>>A>>B;
sort(p,p+n);//对偶数序列进行排序
//边界候选:A附近
if(A%2==1) cand.push_back(A);
else if(A+1<=B) cand.push_back(A+1);
//边界候选:B附近
if(B%2==1) cand.push_back(B);
else if(B-1>=A) cand.push_back(B-1);
//每对相邻偶数之间的候选
for(int i=0;i+1<n;i++){
int sum=p[i]+p[i+1];//两个偶数之和
int mid=sum/2;//中间值(可能为奇数或偶数)
//尝试mid-1,mid,mid+1中的奇数
for(int d=-1;d<=1;d++){
int x=mid+d;
if(x%2==1&&A<=x&&x<=B){
cand.push_back(x);
}
}
}
//枚举候选,计算最优解
int bestX=(A%2==1?A:A+1);//“保底”答案(区间内第一个奇数)
int bestdist=-1;
for(int x : cand){
int mindist=2e9;
for(int i=0;i<n;i++){
int dist=abs(x-p[i]);
if(dist<mindist) mindist=dist;
}
if(mindist>bestdist){
bestdist=mindist;
bestX=x;
}
}
cout<<bestX;
return 0;
}