思路:

#include <bits/stdc++.h>
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<pair<int, int>> 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;
}
该篇文章描述了一个C++程序,主要涉及图的遍历算法和二分搜索技巧,用于在一个给定的整数数组中找到满足特定条件的最大高度和宽度组合。程序解决的问题是检查是否可以找到一个组合,使得总和能被最大高度或宽度整除,并输出所有可能的组合。

被折叠的 条评论
为什么被折叠?



