[题解]CF1819B The Butcher

思路

首先发现对于每一次切割,长和宽只会变化一次。

所以,答案最多只会有两种情况(其中 S 为矩形的面积):

  1. (max{ai},Smax{ai}),其中需要满足 Smodmax{ai}=0
  2. (Smax{bi},max{bi}),其中需要满足 Smodmax{bi}=0

那么,直接判断这两种情况即可。

首先一直将长与当前目标长一样的矩形丢进去,然后将宽与当前目标宽一样的矩形丢进去。

注意在更新长宽的时候,目标长宽也会发生变化,需要时时更新。

在目标长宽其中有一个更新为 0 时,表示此情况成立;如果在更新过程中,发现没有任何一个矩形能够放进去了,表示此情况不成立。

为了代码的可读性,我们可以将 (ai,bi) 用两个数组存起来,分别按照 ai>ajbi>bj 进行排序。

Code

#include <bits/stdc++.h>  
#define fst first  
#define snd second  
#define int long long  
#define re register  
  
using namespace std;  
  
typedef pair<int,int> pii;  
const int N = 2e5 + 10;  
int T,n,s;  
bool vis[N];  
  
struct square{  
    int a;  
    int b;  
    int id;  
}arr[N],brr[N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline bool check(int a,int b){  
    int ida = 1,idb = 1;  
    for (re int i = 1;i <= n;i++) vis[i] = false;  
    while (a > 0 && b > 0){  
        while (ida <= n && vis[arr[ida].id]) ida++;  
        int idxa = ida,idxb = idb;  
        while (ida <= n && arr[ida].a == a){  
            vis[arr[ida].id] = true;  
            b -= arr[ida].b;  
            ida++;  
        }  
        while (idb <= n && vis[brr[idb].id]) idb++;  
        while (idb <= n && brr[idb].b == b){  
            vis[brr[idb].id] = true;  
            a -= brr[idb].a;  
            idb++;  
        }  
        if (idxa == ida && idxb == idb) return false;  
    }  
    if (!a || !b) return true;  
    return false;  
}  
  
signed main(){  
    T = read();  
    while (T--){  
        int A = 0,B = 0,s = 0,num = 0;  
        vector<pii> v;  
        n = read();  
        for (re int i = 1;i <= n;i++){  
            arr[i].a = brr[i].a = read();  
            arr[i].b = brr[i].b = read();  
            arr[i].id = brr[i].id = i;  
            s += arr[i].a * arr[i].b;  
            A = max(A,arr[i].a);  
            B = max(B,arr[i].b);  
        }  
        sort(arr + 1,arr + n + 1,[](const square &a,const square &b){  
            if (a.a != b.a) return a.a > b.a;  
            return a.b > b.b;  
        });  
        sort(brr + 1,brr + n + 1,[](const square &a,const square &b){  
            if (a.b != b.b) return a.b > b.b;  
            return a.a > b.a;  
        });  
        if (s % A == 0 && check(A,s / A)){  
            num++;  
            v.push_back({A,s / A});  
        }  
        if (s % B == 0 && check(s / B,B)){  
            if (v.empty() || (v[0].fst != s / B || v[0].snd != B)){  
                num++;  
                v.push_back({s / B,B});  
            }  
        }  
        printf("%lld\n",num);  
        for (auto p:v) printf("%lld %lld\n",p.fst,p.snd);  
    }  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18266714

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示