当时我想的是两个结构体,都排序,然后记录下标哪个被用过,写着写着觉得太麻烦去看题解,还是大佬的代码简洁,multiset很方便
差距还体现在解决问题的方法上
对大佬代码作简单的注释
#include<iostream>
#include<set>
#define int long long
using namespace std;
const int N = 2e5 + 100;
typedef pair<int,int> pii;
int a[N], b[N], n;
//假设当前为横切,那么把宽度为最大的都找到之后,一定是竖切了,那这个矩形的高一定是当前最高的,再找所有高为
//最高的矩形,他们的宽度占用要减去,找完所有这样的竖切矩形,一定是再找横切…… 不过先谁都一样
bool check(int x,int y) //高和宽
{
multiset<pii> st1,st2;
//一个把高从大到小排序,一个把宽从大到小排序
//横切先取宽大的,竖切先取高大的
for(int i = 1; i <= n; i ++)
{
st1.insert({a[i], b[i]});
st2.insert({b[i], a[i]});
}
for(int i = 1; i <= n; i ++)
{
//找竖切
int tx = st1.rbegin()->first;//当前高
int ty = st1.rbegin()->second;//当前宽
if(tx == x)
{
y -= ty;//把占用的都删掉
st1.erase(st1.find({tx,ty}));
st2.erase(st2.find({ty,tx}));
continue;
}
//找横切
tx = st2.rbegin()->second;
ty = st2.rbegin()->first;
if(ty == y)
{
x -= tx;
st1.erase(st1.find({tx,ty}));
st2.erase(st2.find({ty,tx}));
continue;
}
return false;
}
return true;
}
void solve()
{
cin >> n;
int s = 0;
int mx = 0,my = 0;
for(int i = 1; i <= n; i ++)
{
cin >> a[i] >> b[i];
s += a[i] * b[i];//总面积
mx = max(mx, a[i]);//初始最高
my = max(my, b[i]);//初始最宽
}
set<pii> ans;
if(s % mx == 0 && check(mx, s / mx)) ans.insert({mx, s/mx});
if(s % my == 0 && check(s / my, my)) ans.insert({s/my, my});
cout << ans.size() << endl;
for(auto it:ans) cout << it.first << " " << it.second << endl;
}
signed main()
{
int t = 1;
cin >> t;
while(t --)
solve();
}