Loading

CF51A Cheaterius's Problem 题解

CF51A Cheaterius's Problem 题解

题目分析

这道题是一个很不错的锻炼代码能力的题,主要思路是模拟。

每一张牌都是 \(2\times2\) 的大小。而且如果两张牌通过旋转能重合就是同一张牌,我们可以模拟这一过程。

因为题目中是依次输入每一张牌,所以我们可以采用边读边操作的方法。此题的读入操作是个大工程。

为了方便读入,我们可以用 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\n",k); //最后输出不同的牌的张数 
}

提交记录

题解到此结束,希望大家看完思路自己模拟着打一遍,杜绝抄袭哦~

posted @ 2020-09-05 19:37  EdisonBa  阅读(136)  评论(0编辑  收藏  举报