Weird Sanchola
我们先找到数组中的中位数,在从中位数出发寻找距离中位数最近的素数。设x=n/2,这里要注意的是当n为奇数时,数组的中位数是a[x+n%2]而n为偶数时数组的中位数是a[x],a[x+1]。存在两个值,所以我们要考虑a[x],a[x+1]之间存在的素数。解决这一特殊情况,剩下的就是从中位数开始向两边遍历查找素数,找到后再进行计算,得到最小值。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int N = 1e5+10;
int a[N],n;
bool ask(int x)//判断素数
{
if(x==0||x==1)
return false;
for(int i=2; i<=sqrt(x); i++)
{
if(x%i==0)
return false;
}
return true;
}
long long sum(int x)//计算操作次数
{
long long ans = 0;
for(int i=1; i<=n; i++)
ans+=abs(x-a[i]);
return ans;
}
int main()
{
long long ans = 1e18;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);//从小到大排序
int x = n/2;
if(n%2==0)//n为偶数时处理a[x],a[x+1]之间的数
{
for(int i=a[x]; i<=a[x+1]; i++)
{
if(ask(i))
{
ans = min(ans,sum(i));//ans赋值为最小的值
break;
}
}
}
//无论n为奇数还是偶数均要进行
for(int i=a[x+n%2]; i<=1e18; i++)
{
if(ask(i))
{
ans = min(ans,sum(i));
break;
}
}
for(int i=a[x+n%2]; i>=2; i--)
{
if(ask(i))
{
ans = min(ans,sum(i));
break;
}
}
printf("%lld\n",ans);
return 0;
}