「ARC_172_A_Chocolate」题解

题意

给定一 \(h\times w\) 大小的巧克力,从中分下 \(n\) 块,第 \(i\) 块大小为 \(2^{a_i}\times 2^{a_i}\) 的正方形,问能否成功分(允许原巧克力有剩余)。

  • \(1\leq h\leq 10^9\)
  • \(1\leq w\leq 10^9\)
  • \(1\leq n\leq 1000\)
  • \(0\leq a_i\leq 25\)
  • 题目链接

解法

采取贪心做法。

\(a_i\) 从大到小排序,防止分的太凌乱无法继续分大块。

对于每一次分,取剩余所有块中最大的一块(此处最大指的是 \(\min(x,y)\) 最大,\(x,y\) 表示长和宽)。

对于这一块,如果能继续分当前块,设 \(s=2^{a_i}\) ,则若 \(x>=s\)\(y>=s\) ,则可分出该块。

分出该块后,将其剩余部分继续分成两块,并存起来,如下图:

image

这里可以采用大根堆,当然也可以用数组,但数组的话就要每次从大到小排序,不过也不会超时,数据不大,主要用大根堆的话不好处理他按什么排序。

把新割出来的两块压进去,重复该操作即可。

至于这么割会不会漏情况,由于我们是从大到小排序的,实际上不管横着还是竖着割,都是相差不大的,而且割出来的两个块一定是足够大的。我们每次都取最大的一块割,如果这都不行,那一定是不行。

如果能割到最后,就是 \(Yes\) ,中间没法继续割了的话输出 \(No\) 结束运行就可以了。

代码

#include<bits/stdc++.h>
#define int long long 
#define endl '\n'
using namespace std;
const int N=101000,P=1e9;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=1;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int h,w,n,a[N],sum,cnt;
struct aa
{
    int x,y;
}q[N];
bool cmp(aa a,aa b) 
{
    int x=min(a.x,a.y),y=min(a.x,a.y);
    return x>y;
}
bool dmp(int a,int b) {return a>b;}
signed main()
{
	#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    read(h),read(w),read(n);
    q[++cnt].x=h,q[cnt].y=w;
    for(int i=1;i<=n;i++) read(a[i]),sum+=powl(2,a[i]);
    if(h*w<sum) cout<<"No",exit(0);
    stable_sort(a+1,a+1+n,dmp);
    for(int i=1;i<=n;i++)
    {
        stable_sort(q+1,q+1+cnt,cmp);
        int s=powl(2,a[i]),flag=0;
        for(int j=1;j<=cnt;j++)//此处实际上只进行1次,因为排序了。
            if(q[j].x>=s&&q[j].y>=s)
            {
                int x=q[j].x,y=q[j].y;
                q[j].x=0,q[j].y=0;
                q[++cnt].x=s,q[cnt].y=y-s,
                q[++cnt].x=x-s,q[cnt].y=y;
                flag=1;
                break;
            }
        if(!flag) cout<<"No",exit(0);
    }
    cout<<"Yes";
}
posted @ 2024-02-19 16:22  卡布叻_周深  阅读(44)  评论(0)    收藏  举报