CF 591D Three Logos 暴力,模拟

题意:给出三个矩形的长和宽(x[i],y[i]),问用这三个矩形是否能拼成一个正方形(矩形可以旋转)

输出正方形的边长和拼成的方案.


若sqrt(矩形面积和)正好为某个整数n 则边长为n.

因为只有3个矩形,在左上角放一个以后,剩下两个部分必须填满 暴力判断即可.

#include <bits/stdc++.h>
using namespace std;
const int N=2e3+5;
int n=-1,a[N],res[N][N];
bool equ(int a,int b,int c,int d)
{
	if((a==c&&b==d)||(a==d&&b==c))
		return true;
	return false;
}
void fill(int sx,int sy,int tx,int ty,int op)
{
	for(int i=sx;i<=tx;i++)
		for(int j=sy;j<=ty;j++)
			res[i][j]=op;	
}
void check(int x,int y)
{
	fill(1,1,x,y,0);
	if(equ(a[3],a[4],x,n-y)&&equ(a[5],a[6],n-x,n))
		fill(1,y+1,x,n,1),fill(x+1,1,n,n,2);	
	if(equ(a[3],a[4],n-x,n)&&equ(a[5],a[6],x,n-y))
		fill(1,y+1,x,n,2),fill(x+1,1,n,n,1);	
	if(equ(a[3],a[4],n,n-y)&&equ(a[5],a[6],n-x,y))
		fill(1,y+1,n,n,1),fill(x+1,1,n,y,2);
	if(equ(a[3],a[4],n-x,y)&&equ(a[5],a[6],n,n-y))
		fill(1,y+1,n,n,2),fill(x+1,1,n,y,1);
	if(x==n)
	{
		if(a[3]==a[5]&&a[3]==n-y&&a[4]+a[6]==n)
			fill(1,y+1,a[4],n,1),fill(a[4]+1,y+1,n,n,2);
		if(a[3]==a[6]&&a[3]==n-y&&a[4]+a[5]==n)
			fill(1,y+1,a[4],n,1),fill(a[4]+1,y+1,n,n,2);	
		if(a[4]==a[5]&&a[4]==n-y&&a[3]+a[6]==n)
			fill(1,y+1,a[3],n,1),fill(a[3]+1,y+1,n,n,2);
		if(a[4]==a[6]&&a[4]==n-y&&a[3]+a[5]==n)
			fill(1,y+1,a[3],n,1),fill(a[3]+1,y+1,n,n,2);	
	}
}
int main()
{
	int m=0;
	for(int i=1;i<=6;i++)
		cin>>a[i];
	for(int i=1;i<=6;i+=2)
	{
		m+=a[i]*a[i+1];
		if(a[i]<a[i+1])
			swap(a[i],a[i+1]);
	}
	for(int i=1;i*i<=m;i++)
		if(i*i==m)
		{
			n=i;
			break;
		}
	if(n==-1)
	{
		puts("-1");
		return 0;
	}
	memset(res,-1,sizeof(res));
	check(a[1],a[2]);
	if(res[n][n]==-1)
		check(a[2],a[1]);
	if(res[n][n]==-1)
	{
		fill(1,1,a[1],a[2],0);
		fill(1,a[2]+1,a[3],a[2]+a[4],1);
		fill(1,a[2]+a[4]+1,a[5],a[2]+a[4]+a[6],2);
	}
	bool flag=true;
	for(int i=1;i<=n;i++)		
		for(int j=1;j<=n;j++)
			if(res[i][j]==-1)
				flag=false;	
	if(!flag)
		puts("-1");
	else
	{
		cout<<n<<'\n';
		for(int i=1;i<=n;i++)
		{	
			for(int j=1;j<=n;j++)
				printf("%c",'A'+res[i][j]);
			printf("\n");
		}		
	}
	return 0;
} 

上面代码虽然能AC 一点都不简洁哇....(自己都看不下去...)

可以发现有解的时候 三个矩形肯定有一个长或宽为n. 把最大的矩形先放到最上面.剩余两个在暴力判断.

可以枚举01 来判断一个矩阵是否旋转

#include <bits/stdc++.h>
using namespace std;
int n,m,x[5][5];
char ans[105][105];
void add(int x,int y,int xx,int yy,int zz) {
    char last=('A'+zz-1);
    for (int i=x;i<=x+xx-1;++i)
        for (int j=y;j<=y+yy-1;++j)
            ans[i][j]=last;
}
void prnt(int x) {
    cout<<x<<'\n';
    for (int i=1;i<=x;++i) {
        for (int j=1;j<=x;++j)
            cout<<ans[i][j];
        cout<<'\n';
    }
    exit(0);
}
void check1(int x,int y,int xx,int yy,int xxx,int yyy,int p1,int p2,int p3) {
    if (x==xx+xxx && yy==yyy && y+yy==x) {
        add(1,1,x,y,p1);
        add(1,y+1,xx,yy,p2);
        add(xx+1,y+1,xxx,yyy,p3);
        prnt(x);
        exit(0);
    }
}


int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    for (int i=1;i<=3;++i)
        for (int j=0;j<2;++j)
        cin>>x[i][j];
    for (int i=0;i<2;++i)
        for (int j=0;j<2;++j)
    for (int k=0;k<2;++k) {
        if (x[1][i]==x[2][j] && x[2][j]==x[3][k] && x[1][i]==(x[1][1-i]+x[2][1-j]+x[3][1-k])) {
            add(1,1,x[1][i],x[1][1-i],1);
            add(1,x[1][1-i]+1,x[2][j],x[2][1-j],2);
            add(1,x[1][1-i]+x[2][1-j]+1,x[3][k],x[3][1-k],3);
            prnt(x[1][i]);
        }
    }
    for (int i=1;i<=3;++i)
        for (int j=1;j<=3;++j) if (j!=i)
    for (int k=1;k<=3;++k) if (k!=i && k!=j) {
        for (int z=0;z<2;++z)
            for (int zz=0;zz<2;++zz)
                for (int zzz=0;zzz<2;++zzz) {
                    check1(x[i][z],x[i][1-z],x[j][zz],x[j][1-zz],x[k][zzz],x[k][1-zzz],i,j,k);
                }
    }
    cout<<"-1";
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值