有一个h*w(未知)的矩形,给定n,切n-1次,每切一次,把其中一块放在盒子里,另一块继续切。最后一块也放在盒子里,最终有n块矩形。给定n个矩形的长和宽(n个矩形是乱序的),求初始h,w

题目

思路:

有一个h*w(未知)的矩形,给定n,切n-1次,每切一次,把其中一块放在盒子里,另一块继续切。最后一块也放在盒子里,最终有n块矩形。给定n个矩形的长和宽(n个矩形是乱序的),求初始h,w_第1张图片

#include 
using namespace std;
#define int long long
#define pb push_back
#define fi first
#define se second
#define lson p << 1
#define rson p << 1 | 1
const int maxn = 1e6 + 5, inf = 1e18, maxm = 4e4 + 5, mod = 1e9 + 7;
int a[maxn], b[maxn];
// int k[maxn];
bool vis[maxn];
int n, m;
string s;
struct Node{
	int h, w, id;
}c[maxn], d[maxn];

bool cmp(Node x, Node y){
	return x.h > y.h;
}

bool cmp2(Node x, Node y){
	return x.w > y.w;
}

bool check(int h, int w){
	int i = 1, j = 1;
	for(int i = 1; i <= n; i++){
		vis[i] = 0;
	}
	while(h && w){
		bool flag = 0;
		while(i <= n && (c[i].h == h || vis[c[i].id])){//vis[c[i].id]一定得写,有可能c[i + 1].h == h但是c[i].h != h(这个被j用了)
			if(vis[c[i].id]){
				i++;
				continue;
			}
			vis[c[i].id] = 1;
			w -= c[i].w;
			flag = 1;
			i++;
		}
		while(j <= n && (d[j].w == w || vis[d[j].id])){
			if(vis[d[j].id]){
				j++;
				continue;
			}
			vis[d[j].id] = 1;
			h -= d[j].h;
			flag = 1;
			j++;
		}
		if(!flag && h && w){
			return 0;
		}
	}
	return 1;
}

void solve(){
    int res = 0;
    // int k;
    int x;
    int q;
	// cin >> s;
    cin >> n;
	int sum = 0;
	for(int i = 1; i <= n; i++){
		cin >> a[i] >> b[i];
		c[i] = {a[i], b[i], i};
		d[i] = {a[i], b[i], i};
		sum += a[i] * b[i];
	}
	sort(c + 1, c + n + 1, cmp);
	sort(d + 1, d + n + 1, cmp2);
	int maxh = c[1].h, maxw = d[1].w;
	set> ans;
	if(sum % maxh == 0 && check(maxh, sum / maxh)){
		ans.insert({maxh, sum / maxh});
	}
	if(sum % maxw == 0 && check(sum / maxw, maxw)){
		ans.insert({sum / maxw, maxw});
	}
	cout << ans.size() << '\n';
	for(auto [x, y] : ans){
		cout << x << ' ' << y << '\n';
	}
}
    
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T = 1;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

你可能感兴趣的:(codeforces,算法)