因为每次是直接断裂成两块,所以如果考虑从初状态转移,则一定存在一块的宽或高等于目前剩余的矩形
并且容易想到,我们剩余的这个矩形是不断变小的,所以每次只需要看剩余的最大宽或最大高即可
AC代码
Details
#include<bits/stdc++.h>
using namespace std;
#define QAQ return
#define QWQ return 0;
#define ll long long
#define pii pair< int,int >
const int N=2e5+10;
struct value
{
int h, w, idx;
bool operator< ( const value &x )const
{
if( h == x.h ) QAQ w < x.w;
QAQ h < x.h;
}
};
pii ans[N];
bool vis[N];
int main()
{
ios::sync_with_stdio( false );
cin.tie( nullptr ), cout.tie( nullptr );
int H, W, n;
cin>>H>>W>>n;
priority_queue< value > ph, pw;
for( int i=1, h, w;i<=n;i++ ) cin>>h>>w, ph.push( { h,w,i } ), pw.push( { w,h,i } );
int nh=H, nw=W;
for( int i=1;i<=n;i++ )
{
while( !ph.empty() && vis[ph.top().idx] ) ph.pop();
while( !pw.empty() && vis[pw.top().idx] ) pw.pop();
auto [h1,w1,idx1]=ph.top();
auto [h2,w2,idx2]=pw.top();
if( h1 == nh ) ans[idx1]={ H-nh+1,W-nw+1 }, nw-=w1, vis[idx1]=true, ph.pop();
else if( h2 == nw ) ans[idx2]={ H-nh+1,W-nw+1 }, nh-=w2, vis[idx2]=true, pw.pop();
}
for( int i=1;i<=n;i++ ) cout<<ans[i].first<<" "<<ans[i].second<<"\n";
QWQ
}
时间复杂度:O(nlogn)