CF51A Cheaterius's Problem 题解
题目分析
这道题是一个很不错的锻炼代码能力的题,主要思路是模拟。
每一张牌都是 (2 imes2) 的大小。而且如果两张牌通过旋转能重合就是同一张牌,我们可以模拟这一过程。
因为题目中是依次输入每一张牌,所以我们可以采用边读边操作的方法。此题的读入操作是个大工程。
为了方便读入,我们可以用 char 形式的字符读入,读入之后转成 int 类型。然后把 (a,b,c,d) 与 (f) 数组中的数相比较。如果它们是相同的牌,则让总牌数+1;否则就把这四个数存入 (f) 数组,代表多了一张不同的牌。
存储每一张牌,我们可以采用三维数组 f[i][j][k]
来存储,其中 (k) 表示不同的牌的张数。 我们设左上角的牌为 (a) ,右上角的牌为 (b) ,左下角为 (c) ,右下角为 (d) 。则有:
读入操作代码:
char x;
cin>>x>>x; //读入星号
cin>>ch1>>ch2;
cin>>ch3>>ch4;
int a=ch1-'0',b=ch2-'0'; // char 转 int
int c=ch3-'0',d=ch4-'0';
f[1][1][1]=a; //存入 f 数组
f[1][2][1]=b;
f[2][1][1]=c;
f[2][2][1]=d;
核心部分是枚举出所有是一张牌的情况。我们可以依次旋转90度枚举即可。操作过程如下图所示:
代码表示所有可能情况:
if(a==f[1][1][j] && b==f[1][2][j] && c==f[2][1][j] && d==f[2][2][j])
if(c==f[1][1][j] && a==f[1][2][j] && d==f[2][1][j] && b==f[2][2][j])
if(d==f[1][1][j] && c==f[1][2][j] && b==f[2][1][j] && a==f[2][2][j])
if(b==f[1][1][j] && d==f[1][2][j] && a==f[2][1][j] && c==f[2][2][j])
最后输出 (f) 数组中的 (k) 即可。
代码
#include<iostream>
#include<cstdio>
using namespace std;
int f[3][3][1003];
int main()
{
int n;
char ch1,ch2,ch3,ch4;
//下面单独读入第一组数据,因为第一组数据上面没有星号
cin>>n;
cin>>ch1>>ch2;
cin>>ch3>>ch4;
f[1][1][1]=ch1-'0'; // char 转 int 存入
f[1][2][1]=ch2-'0';
f[2][1][1]=ch3-'0';
f[2][2][1]=ch4-'0';
int k=1; // k 代表不同的牌的张数
for(int i=2;i<=n;++i) // 从第2张牌继续读入
{
bool ok=0; //临时 bool 数组,用来判断两张牌是不是相同的
char x;
cin>>x>>x;
cin>>ch1>>ch2;
cin>>ch3>>ch4;
int a=ch1-'0';
int b=ch2-'0';
int c=ch3-'0';
int d=ch4-'0';
for(int j=1;j<=k;++j) //在每张不同的牌之间枚举,看看此牌和之前的牌是不是相同
{
if(a==f[1][1][j] && b==f[1][2][j] && c==f[2][1][j] && d==f[2][2][j])
{
ok=1; //完全相同的情况
break;//如果和之前的牌相同,则可以跳出循环,继续读入下一组数据
}
if(c==f[1][1][j] && a==f[1][2][j] && d==f[2][1][j] && b==f[2][2][j])
{
ok=1; //顺时针旋转90度
break;//同上
}
if(d==f[1][1][j] && c==f[1][2][j] && b==f[2][1][j] && a==f[2][2][j])
{
ok=1;//顺时针旋转180度
break;//同上
}
if(b==f[1][1][j] && d==f[1][2][j] && a==f[2][1][j] && c==f[2][2][j])
{
ok=1;//顺时针旋转270度
break;//同上
}
}
if(ok==0) //如果这张牌和前面的各不相同,那么把这张牌存入 f 数组
{
f[1][1][++k]=ch1-'0';
f[1][2][k]=ch2-'0';
f[2][1][k]=ch3-'0';
f[2][2][k]=ch4-'0';
}
}
printf("%d
",k); //最后输出不同的牌的张数
}
题解到此结束,希望大家看完思路自己模拟着打一遍,杜绝抄袭哦~