洛谷P1205 [USACO1.2] 方块转换 Transformations

题目描述

一块 𝑛×𝑛 正方形的黑白瓦片的图案要被转换成新的正方形图案。写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:

  • 转 90°:图案按顺时针转 90°。

  • 转 180°:图案按顺时针转 180°。

  • 转 270°:图案按顺时针转 270°。

  • 反射:图案在水平方向翻转(以中央铅垂线为中心形成原图案的镜像)。

  • 组合:图案在水平方向翻转,然后再按照 1∼3 之间的一种再次转换。

  • 不改变:原图案不改变。

  • 无效转换:无法用以上方法得到新图案。

如果有多种可用的转换方法,请选择序号最小的那个。

只使用上述 7 个中的一个步骤来完成这次转换。

输入格式

第一行一个正整数 𝑛。

然后 𝑛 行,每行 𝑛 个字符,全部为 @ 或 -,表示初始的正方形。

接下来 𝑛 行,每行 𝑛 个字符,全部为 @ 或 -,表示最终的正方形。

输出格式

单独的一行包括 1∼7 之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的转换方法。

输入输出样例

输入 #1

3
@-@
---
@@-
@-@
@--
--@

输出 #1

1

说明/提示

【数据范围】
对于 100% 的数据,1≤𝑛≤10。

题目翻译来自 NOCOW。

USACO Training Section 1.2

大致思路:

1.首先实现顺时针旋转90°、180°、270°:

90°:c[j][n-1-i]=a[i][j];180°:c[n-1-i][n-1-j]=a[i][j];270°:c[n-1-j][i]=a[i][j];(0<=i,j<n)

2.利用memcmp函数来判断待比较方块和标准方块是否完全方块(完全相同,memcmp会返回0,否则会返回非零值)

3.在执行第四个操作时,首先使用memcpy函数复制方块,再给复制好的方块做镜像对称。

参考代码:

#include<bits/stdc++.h>
using namespace std;
const int N=15;
int n;
char a[N][N],b[N][N],c[N][N];
char s[N][N];
bool work1()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-i;
			c[j][k]=a[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
bool work2()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-i,l=n-1-j;
			c[k][l]=a[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
bool work3()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-j;
			c[k][i]=a[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
void work4()
{
	memcpy(b,a,sizeof a);
	for(int i=0;i<n;i++)
		for(int j=0;j<n/2;j++)
			swap(b[i][j],b[i][n-1-j]);
}
bool work5()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-i;
			c[j][k]=b[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
bool work6()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-i,l=n-1-j;
			c[k][l]=b[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
bool work7()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k=n-1-j;
			c[k][i]=b[i][j];
		}
	return !memcmp(c,s,sizeof s);
}
int scheme()
{
	if(work1()) return 1;
	else if(work2()) return 2;
	else if(work3()) return 3;
	else
	{
		work4();
		if(!memcmp(b,s,sizeof s)) return 4;
		else if(work5()||work6()||work7()) return 5;
		else if(!memcmp(a,s,sizeof s)) return 6;
		else return 7;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%s",a[i]);
	for(int i=0;i<n;i++) scanf("%s",s[i]);
	printf("%d\n",scheme());
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值