牛客 牛牛的揠苗助长 题解 (中位数+二分) 2019 USP-ICMC J. Weird Sanchola 题解(中位数+相邻的质数的最大差值)

牛牛的揠苗助长

题目思路

1:如果不增加,那么肯定是靠齐中位数,类似于仓库选址。

2:假设经过无限长的时间后,我终于将所有水稻都调整到了一样高,这个同样高的高度是否能持续保持?显然是可以的对吧,因为每一天都仅有一个水稻的高度长高,所以我只要将自然长的水稻给他摁回去,就能一直保持他们都是同样高的。所以满足单调性可以二分。

代码

#include
#include
#include
typedef long long ll;
using namespace std;
const int maxn=1e5+5;
ll n,a[maxn],b[maxn];
bool check(ll x){
     
    for(int i=1;i<=n;i++){
     
        b[i]=a[i]+x/n+(i<=x%n);
    }
    sort(b+1,b+1+n);
    ll cha=0;
    for(int i=1;i<=n;i++){
     
        cha+=b[(n+1)/2]-b[i]>0?(b[(n+1)/2]-b[i]):(-b[(n+1)/2]+b[i]);
    }
    return cha<=x;
}
int main(){
     
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
     
        scanf("%lld",&a[i]);
    }
    ll l=1,r=1e18,ans=-1;
    while(l<=r){
     
        ll mid=(l+r)/2;
        if(check(mid)){
     
            ans=mid;
            r=mid-1;
        }else{
     
            l=mid+1;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

Weird Sanchola

题目思路

这个也是到同一高度,但是这个是同一高度的质数。

有一个知识点要注意 1到1e9内相邻的质数最大差值大约 300左右.1到1e18大约1500左右.

维基百科有一个这样的表 https://en.wikipedia.org/wiki/Prime_gap

所以直接暴力就行了,qwq我居然以为质数的间隔可能会非常大

代码

#include
#include
#include
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
int n,a[maxn];
ll ans=2e18;
bool check(int x){
     
    if(x==1){
     //特判!!!
        return false;
    }
    for(int i=2;i<=sqrt(x);i++){
     
        if(x%i==0){
     
            return false;
        }
    }
    return true;
}
ll cal(int x){
     
    ll sum=0;
    for(int i=1;i<=n;i++){
     
        sum+=abs(a[i]-x);
    }
    return sum;
}
int main(){
     
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
     
        scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);//要先sort
    if(n%2==0){
     
        for(int i=a[n/2];i<=a[n/2+1];i++){
     
            if(check(i)){
     
                ans=min(ans,cal(i));
                break;
            }
        }
        for(int i=a[n/2];i>=1;i--){
     
            if(check(i)){
     
                ans=min(ans,cal(i));
                break;
            }
        }
        for(int i=a[n/2+1];i;i++){
     
            if(check(i)){
     
                ans=min(ans,cal(i));
                break;
            }
        }
    }else{
     
        for(int i=a[n/2+1];i;i++){
     
            if(check(i)){
     
                ans=min(ans,cal(i));
                break;
            }
        }
        for(int i=a[n/2+1];i>=1;i--){
     
             if(check(i)){
     
                ans=min(ans,cal(i));
                break;
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(思维)