思路: 枚举花费多少次进行全体上移,找到上移x次后还需要至少多少次右移即可。 具体做法:先找到所有不合法的对,按需要上移次数排序,用数组记录后缀右动的最大值,然后枚举的时候用双指针维护一下就行。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int n,m; struct uzi{ int x,y; }p[N],q[N]; int x[N*20]; pair<int,int>s[N*20]; int cnt; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++)cin>>p[i].x>>p[i].y; for(int i=1;i<=m;i++)cin>>q[i].x>>q[i].y; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(q[j].y>=p[i].y&&q[j].x>=p[i].x){ s[++cnt]={q[j].y-p[i].y+1,q[j].x-p[i].x+1}; } } } sort(s+1,s+1+cnt); for(int i=cnt;i>=1;i--)x[i]=max(x[i+1],s[i].se); int ans=1000005,pos=1; for(int i=0;i<=1000000&&i<ans;i++){//up while(pos<=cnt &&s[pos].fi<=i)pos++; ans=min(ans,i+x[pos]); } cout<<ans<<'\n'; return 0; }