解题报告 之 CodeForces 581D Three Logos

本文介绍了一道编程竞赛题目的解决方案,题目要求判断三个矩形是否能够组合成一个正方形,并输出组合方式。文章给出了具体的实现代码,并分享了解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题报告 之 CodeForces 581D Three Logos


Description

Three companies decided to order a billboard with pictures of their logos. A billboard is a big square board. A logo of each company is a rectangle of a non-zero area.

Advertisers will put up the ad only if it is possible to place all three logos on the billboard so that they do not overlap and the billboard has no empty space left. When you put a logo on the billboard, you should rotate it so that the sides were parallel to the sides of the billboard.

Your task is to determine if it is possible to put the logos of all the three companies on some square billboard without breaking any of the described rules.

Input

The first line of the input contains six positive integers x1, y1, x2, y2, x3, y3 (1 ≤ x1, y1, x2, y2, x3, y3 ≤ 100), where xi and yi determine the length and width of the logo of the i-th company respectively.

Output

If it is impossible to place all the three logos on a square shield, print a single integer "-1" (without the quotes).

If it is possible, print in the first line the length of a side of square n, where you can place all the three logos. Each of the next n lines should contain n uppercase English letters "A", "B" or "C". The sets of the same letters should form solid rectangles, provided that:

  • the sizes of the rectangle composed from letters "A" should be equal to the sizes of the logo of the first company,
  • the sizes of the rectangle composed from letters "B" should be equal to the sizes of the logo of the second company,
  • the sizes of the rectangle composed from letters "C" should be equal to the sizes of the logo of the third company,

Note that the logos of the companies can be rotated for printing on the billboard. The billboard mustn't have any empty space. If a square billboard can be filled with the logos in multiple ways, you are allowed to print any of them.

See the samples to better understand the statement.

Sample Input

Input
5 1 2 5 5 2
Output
5
AAAAA
BBBBB
BBBBB
CCCCC
CCCCC
Input
4 4 2 6 4 2
Output
6
BBBBBB
BBBBBB
AAAACC
AAAACC
AAAACC
AAAACC

Source


题目大意:给你三个矩形的长宽高,问你能不能拼成一个正方形,如果能,则输出三个矩形的分布(分别对应A、B、C字符)。如果不能,输出-1。

分析:一道大水。还是要冷静才行啊。。。这个题首先明确能构成正方形的条件就是:最长边^2=三个矩形的面积和,同时这个最长边即作为正方形的边长len。具体地,首先得到三个矩形的长宽,先旋转为卧倒的矩形(上下边>=左右腰)。之后找到最长边,判断能否构成正方形。如果能,那么这个最长边的矩形一定可以卧放在正方形的顶部(也可以放在其他地方,但一定可以旋转到顶部)。

然后剩下下面的部分,这个地方有一些陷阱,最简单规避陷阱的方法就是分情况讨论,要不然就是三个矩形都依次卧放;要不就是两个矩形都竖着放。那么就试一下咯,随便选一个剩下的矩形(这里称之为X),如果X的较长边==len或者X的较短边刚好加上顶上矩形的腰长==len,那么就不用旋转;否则就旋转。最后的一个矩形把剩下的地方补齐即可。

上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;

struct Rec
{
	int l, w;
	char ch;
	bool operator <( const Rec& rhs )const
	{
		return l < rhs.l;
	}
	int sq()
	{
		return l*w;
	}
};

Rec rec[4];



int main()
{
	while(scanf( "%d%d%d%d%d%d", &rec[1].l, &rec[1].w, &rec[2].l, &rec[2].w, &rec[3].l, &rec[3].w ) == 6)
	{
		for(int i = 1; i <= 3; i++)
		{
			if(rec[i].l < rec[i].w)swap( rec[i].l, rec[i].w );
			rec[i].ch = 'A' - 1 + i;
		}

		sort( rec + 1, rec + 4 );

		int len = rec[3].l;

		if((rec[3].l*rec[3].l) != (rec[1].sq() + rec[2].sq() + rec[3].sq()))
		{
			printf( "-1\n" );
			continue;
		}

		printf( "%d\n", len );

		for(int i = 1; i <= rec[3].w; i++)
		{
			for(int j = 1; j <= rec[3].l; j++)
			{
				printf( "%c", rec[3].ch );
			}
			printf( "\n" );
		}

		if(rec[2].l!=len&&rec[3].w + rec[2].w != len) swap( rec[2].l, rec[2].w );
		for(int i = 1; i <= rec[2].w; i++)
		{
			for(int j = 1; j <= rec[2].l; j++)
			{
				printf( "%c", rec[2].ch );
			}
			for(int j = 1; j <= len - rec[2].l; j++)
			{
				printf( "%c", rec[1].ch );
			}
			printf( "\n" );
		}

		for(int i = 1; i <=len-rec[3].w- rec[2].w; i++)
		{
			for(int j = 1; j <= len; j++)
			{
				printf( "%c", rec[1].ch );
			}
			printf( "\n" );
		}


	}
	return 0;
}

首先再次赞叹队友叔叔的高智商。另外第一次感到做CF的乐趣在于一定要保持头脑的清晰,就会发现其实都不难。
区域赛加油!祝前队长大大拿金牌~
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值