题解 P1205 【[USACO1.2]方块转换 Transformations】
MyukiyoMekya · · 题解
这种题就是纯模拟,但是模拟最好是用模块化(函数)来写,否则很容易出错
我们每次操作大概的模型为:
for(int i=1,u=1;i<=n;++i,++u)
for(int j=1,v=1;j<=n;++j,++v)
out[u][v]=in[i][j];
先来分析一下每种情况:
第一种
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
变为
| 7 | 4 | 1 |
| 8 | 5 | 2 |
| 9 | 6 | 3 |
发现
for(int i=1,v=n;i<=n;++i,--v)
for(int j=1,u=1;j<=n;++j,++u)
out[u][v]=in[i][j];
第二种要变为:
| 9 | 8 | 7 |
| 6 | 5 | 4 |
| 3 | 2 | 1 |
发现
for(int i=1,u=n;i<=n;++i,--u)
for(int j=1,v=n;j<=n;++j,--v)
out[u][v]=in[i][j];
第三种:
| 3 | 6 | 9 |
| 2 | 5 | 8 |
| 1 | 4 | 7 |
发现
for(int i=1,v=1;i<=n;++i,++v)
for(int j=1,u=n;j<=n;++j,--u)
out[u][v]=in[i][j];
第四种:
| 3 | 2 | 1 |
| 6 | 5 | 4 |
| 9 | 8 | 7 |
发现
for(int i=1,u=1;i<=n;++i,++u)
for(int j=1,v=n;j<=n;++j,--v)
out[i][j]=in[u][v];
到此为止,四种基本操作都写完了
第五种其实就是叫你先做一遍第四种操作,然后再做第一或第二或第三种操作,然后判断
第六种直接判断
判断的话就是里两个
模块化见我代码:
#include <cstdio>
using namespace std;
const int MaxN=11;
char fin[MaxN][MaxN]; //给的转换后的正方形
int n;
void print(char a[][MaxN]) //传入二维数组
{ //调试用的,输出这个二维数组
for(int i=1;i<=n;++i)
puts(a[i]+1);
return;
}
bool pd(char a[][MaxN],char b[][MaxN]) //判断是否相同
{
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(a[i][j]^b[i][j]) // ^为异或,在这里可以理解为!=
return false;
return true;
}
bool _1(char mp[][MaxN]) //第一种操作
{
char a[MaxN][MaxN];
for(int i=1,v=n;i<=n;++i,--v)
for(int j=1,u=1;j<=n;++j,++u)
a[u][v]=mp[i][j];
return pd(a,fin);
}
bool _2(char mp[][MaxN]) //第二种操作
{
char a[MaxN][MaxN];
for(int i=1,u=n;i<=n;++i,--u)
for(int j=1,v=n;j<=n;++j,--v)
a[u][v]=mp[i][j];
return pd(a,fin);
}
bool _3(char mp[][MaxN]) //第三种操作
{
char a[MaxN][MaxN];
for(int i=1,v=1;i<=n;++i,++v)
for(int j=1,u=n;j<=n;++j,--u)
a[u][v]=mp[i][j];
return pd(a,fin);
}
bool _4(char mp[][MaxN]) //第四种操作
{
char a[MaxN][MaxN];
for(int i=1,u=1;i<=n;++i,++u)
for(int j=1,v=n;j<=n;++j,--v)
a[i][j]=mp[u][v];
return pd(a,fin);
}
bool _5(char mp[][MaxN]) //第五种操作
{
char a[MaxN][MaxN];
for(int i=1,u=1;i<=n;++i,++u)
for(int j=1,v=n;j<=n;++j,--v)
a[i][j]=mp[u][v]; //先做一边第四种操作
if(_1(a)) //试一试第一种操作能不能是变换后的正方形相同
return true;
else if(_2(a)) //尝试第二种
return true;
else if(_3(a)) //尝试第三种
return true;
return false;
}
bool _6(char mp[][MaxN]) //第六种操作
{
return pd(mp,fin); //直接返回判断
}
int main(void)
{
char mp[MaxN][MaxN];
scanf("%d",&n);
for(int i=1;i<=n;++i) //读入原始正方形
scanf("%s",mp[i]+1); //+1是为了从下标1开始存储
for(int i=1;i<=n;++i)
scanf("%s",fin[i]+1); //读入变换后正方形
if(_1(mp)) //尝试每一种情况
return puts("1"),0;
else if(_2(mp))
return puts("2"),0;
else if(_3(mp))
return puts("3"),0;
else if(_4(mp))
return puts("4"),0;
else if(_5(mp))
return puts("5"),0;
else if(_6(mp))
return puts("6"),0;
return puts("7"),0;
}