The Butcher

当时我想的是两个结构体,都排序,然后记录下标哪个被用过,写着写着觉得太麻烦去看题解,还是大佬的代码简洁,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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值