二分有啥不对的吗?

P1678 烦恼的高考志愿

baojiaming01 @ 2023-03-18 22:39:14

#include<bits/stdc++.h>
using namespace std;
int a[100001],b[100001];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    for(int i=1; i<=m; i++) cin>>b[i];
    sort(a+1,a+1+n);
    long long ans=0;
    for(int i=1; i<=m; i++)
    {
        int l=1, r=n+1;
        while(l<=r)
        {
            int mid=l+r/2;
            if(a[mid]>=b[i]) l=mid-1;
            else if(a[mid]<=b[i]) r=mid;
        }
        if(b[i]<=a[1]) ans=ans+a[1]-b[i];
        else ans=ans+min(abs(a[l-1]-b[i]),abs(a[l]-b[i]));
    }
    cout<<ans<<endl;
    return 0;
}

全TLE~~~


by baojiaming01 @ 2023-03-18 22:39:58

dalao求解~~~


by Tjaweiof @ 2023-04-03 19:38:37

@baojm 你while中的

if(a[mid]>=b[i]) l=mid-1;

改成

if(a[mid]>b[i]) l=mid+1;

下一行改成

r = mid - 1;

然后再加一行

else if (a[mid] == b[i]) break;

试试看


by Tjaweiof @ 2023-04-03 19:39:26

……还有,那个sort太慢了,换成归并吧。。。


by Tjaweiof @ 2023-04-03 19:50:58

改成这样:

#include<bits/stdc++.h>
using namespace std;
int a[100001],b[100001], c[100001];
void merge(int A[], int B[], int left, int mid, int right){
    int i = left, j = mid + 1, k = left;
    while (i <= mid && j <= right){
        if (A[i] <= A[j]){
            B[k] = A[i];
            k++;
            i++;
        } else {
            B[k] = A[j];
            k++;
            j++;
        }
    }
    while (i <= mid){
        B[k] = A[i];
        k++;
        i++;
    }
    while (j <= right){
        B[k] = A[j];
        k++;
        j++;
    }
    for (i = left; i <= right; i++){
        A[i] = B[i];
    }
}
void mergeSort(int A[], int B[], int left, int right){
    if (left < right){
        int mid = (left + right) / 2;
        mergeSort(A, B, left, mid);
        mergeSort(A, B, mid + 1, right);
        merge(A, B, left, mid, right);
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    for(int i=1; i<=m; i++) cin>>b[i];
    mergeSort(a, c, 0, n - 1);
    long long ans=0;
    for (int i=1; i<=m; i++){
        int l=1, r=n+1;
        while (l < r){
            int mid = l + r / 2;
            if (a[mid] > b[i]) l=mid+1;
            else if (a[mid] < b[i]) r=mid;
            else if (a[mid] == b[i]) break;
        }
        if (b[i]<=a[1]) ans=ans+a[1]-b[i];
        else ans = ans + min(abs(a[l-1] - b[i]), abs(a[l] - b[i]));
    }
    cout << ans << endl;
    return 0;
}

|