#322 (div.2) D. Three Logos

1.题目描述:点击打开链接

2.解题思路:本题要求判断能否找一个正方形,使得恰好可以装下三个矩形。如果可以并输出。首先可以知道,正方形的边长一定是矩形中最大的边长,而且一定有一个矩形是一整条边完整覆盖一个正方形的边长的,因此除去这个矩形后,就是枚举剩下2个矩形的摆放方式了。每个矩形有4种摆放方式,逐个测试,如果均不可行,说明无解。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<list>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int,int> P;


const int N=300+10;
int g[N][N];

int a[6];
int vis[3];
int len;

void draw(int id,int sx,int sy,int h,int w)
{
    for(int i=sx;i<sx+h;i++)
        for(int j=sy;j<sy+w;j++)
        g[i][j]=id;
}

bool check()
{
    for(int i=0;i<len;i++)
    for(int j=0;j<len;j++)
    if(g[i][j]==-1)return false;
    return true;
}

bool test(int sx,int sy)
{
    if(check())
    {
        for(int i=0;i<3;i++)
            if(!vis[i])return false;
        return true;
    }
    int tmp[4];
    int cnt=0;
    for(int i=0;i<6;i+=2)
        if(!vis[i/2])
        {
            if(a[i]==len&&a[i+1]+sx<=len)
            {
                vis[i/2]=1;
                draw(i/2,sx,sy,a[i+1],a[i]);
                if(test(sx+a[i+1],sy))return true;
            }
            else if(a[i]==len-sx&&a[i+1]+sy<=len)
            {
                vis[i/2]=1;
                draw(i/2,sx,sy,a[i],a[i+1]);
                if(test(sx,sy+a[i+1]))return true;
            }
            else if(a[i+1]==len&&a[i]+sx<=len)
            {
                vis[i/2]=1;
                draw(i/2,sx,sy,a[i],a[i+1]);
                if(test(sx+a[i],sy))return true;
            }
            else if(a[i+1]==len-sx&&a[i]+sy<=len)
            {
                vis[i/2]=1;
                draw(i/2,sx,sy,a[i+1],a[i]);
                if(test(sx,sy+a[i]))return true;
            }
        }
    return false;
}
int main()
{
    while(~scanf("%d",&a[0]))
    {
        memset(g,-1,sizeof(g));
        me(vis);
        for(int i=1;i<6;i++)
            scanf("%d",&a[i]);
        len=*max_element(a,a+6);
        for(int i=0;i<6;i+=2)
        {
            if(a[i]<a[i+1])swap(a[i],a[i+1]);
            if(a[i]==len)
            {
                vis[i/2]=1;
                draw(i/2,0,0,a[i+1],a[i]);
                if(test(a[i+1],0))
                {
                    printf("%d\n",len);
                    for(int i=0;i<len;i++)
                        for(int j=0;j<len;j++)
                        printf("%c%s",'A'+g[i][j],j==len-1?"\n":"");
                }
                else puts("-1");
                break;
            }
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值