Atcoder Grand Contest 021 C 题解

Atcoder Grand Contest 021 C 题解

题意

给定N*M的方格,2*1的方块A的个数,1*2的方块B的个数,想知道能否把A和B全部放入方格中,方格可以留空。

笺释

这道题我也没A掉,写一下对别人题解的理解。
//最大空间利用的原则:先要把大的n*m的矩形划分成若干个规则2*2图形和剩余部分
//因为2*2的矩形是一种规则的 不需要额外处理的矩形,而我们的算法毕竟只能处理规则的,不需要额外处理的东西
//我们想要给出一个算法让所有矩形自发的填好并且占据最大空间。
//如果n是奇数,那么一定不能把大矩形全部划分成2*2的矩形,所以如果n是奇数就把第n行填满2*1的矩形
//如果m是偶数,那么一定不能把大矩形全部划分成2*2的矩形,所以如果m是奇数就把第m行填满1*2的矩形
//在进行完这样的处理后,就相当于得到了一个偶数乘偶数尺寸的矩形。
//然后就是贪心放置了,有就放,最后注意右下角的3*3需要处理,需要给定一种特殊方式把中间空出来,这样3*3的空间能最大利用放4个方块

完整代码

#include<bits/stdc++.h>
using namespace std;
char s[1010][1010];
int n,m,a,b;
int main(){
    scanf("%d%d%d%d",&n,&m,&a,&b);
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)s[i][j]='.';
    if(n&1)for(int i=1;i<m&&a;i+=2)s[n][i]='<',s[n][i+1]='>',a--;
    if(m&1)for(int i=1;i<n&&b;i+=2)s[i][m]='^',s[i+1][m]='v',b--;
    for(int i=1;i<n;i+=2)
        for(int j=1;j<m;j+=2){
            if(a>=2){
                a-=2;
                s[i][j]='<',s[i][j+1]='>';
                s[i+1][j]='<',s[i+1][j+1]='>';
            } else if(b>=2){
                b-=2;
                s[i][j]='^',s[i][j+1]='^';
                s[i+1][j]='v',s[i+1][j+1]='v';
            }
            else if(a&&b&&i==n-2&&j==m-2){
                a--,b--;
                s[i][j]='<',s[i][j+1]='>',s[i][j+2]='^';
                s[i+1][j]='^',s[i+1][j+2]='v';
                s[i+2][j]='v',s[i+2][j+1]='<',s[i+2][j+2]='>';
            }
             else if(a){
                a--;
                s[i][j]='<',s[i][j+1]='>';
            } else if(b){
                b--;
                s[i][j]='^',s[i+1][j]='v';
            }
        }
    if(a||b)return puts("NO"),0;
    puts("YES");
    for(int i=1;i<=n;++i)puts(s[i]+1);
}

By @yfzcsc

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值