二分答案。
思路:对于二分给定的mid,即当前允许移动的最大重量,我们可以把小于改重量的标记一下,然后把没有标记的按照顺序放到另一个数组,然后判断是否满足两两相同。
#include<bits/stdc++.h> using namespace std; const int N=1E6+7; int arr[N]; int brr[N]; int crr[N]; bool mark[N],mark1[N]; const int INF=1e9+7; const int mm=1e9; int n; bool judge(int x){ memset(mark,0,sizeof(mark)); memset(mark1,0,sizeof(mark1)); for(int i=1;i<=n;i++) { if(arr[i]<=x) mark[i]=1; if(brr[i]<=x) mark1[i]=1; } int pos=0; for(int i=1;i<=n;i++){ if(mark[i]==0) crr[++pos]=arr[i]; } if(pos&1) return 0; for(int i=1;i<=pos;i+=2){ if(crr[i]!=crr[i+1]) return 0; } pos=0; for(int i=1;i<=n;i++){ if(mark1[i]==0) crr[++pos]=brr[i]; } if(pos&1) return 0; for(int i=1;i<=pos;i+=2) { if(crr[i]!=crr[i+1]) return 0; } return 1; } void solve(){ cin>>n; for(int i=1;i<=n;i++) scanf("%d",&arr[i]); for(int j=1;j<=n;j++) scanf("%d",&brr[j]); int l=0,r=mm; int ans=INF; while(l<=r){ int mid=(l+r)/2; if(judge(mid)){ r=mid-1; ans=min(ans,mid); } else l=mid+1; } cout<<ans<<endl; } int main(){ solve(); return 0; }