week10——实验(大模拟)

目录

    • A - 签到题 :
      • 问题描述
          • 题目简述
          • 输入/输出格式
          • 样例
      • 问题分析
          • 解题思路
          • 参考代码
      • 心得体会
    • B - 东东转魔方:
      • 问题描述
          • 题目简述
          • 输入/输出格式
          • 样例
      • 问题分析
          • 解题思路
          • 参考代码
      • 心得体会

A - 签到题 :

问题描述

题目简述

东东有一个字符串X,该串包含偶数个字符,一半是 S 字符,一半是 T 字符
东东可以对该字符串执行 1010000 次操作:如果存在 ST 是该串的子串,则删除掉最左边的 ST。
即 TSTTSS⇒TTSS、SSSTTT⇒SSTT⇒ST⇒空

输入/输出格式

输入格式:
一个字符串X,(2 ≦ |X| ≦ 200,000)
输出格式:
输出最终串的长度

样例

输入样例:
TSTTSS
输出样例:
4

问题分析

解题思路

字符串里面消去目标子串,思路比较明确,从前向后遍历字符串,如果发现当前遍历位置为子串的第一个字符,而之后为另一个字符,则当前位置前移一个,遍历位置向后移动一个,即删除了子串。遍历后输出最终总长度即可。

参考代码
#include 
#include 

using namespace std;

int main()
{
	string str;
	cin>>str;
	char a[200200];
	a[0]='Q';
	int length=0;
	for(int i=0;i<str.length();i++)
	{
	    if(str[i]=='T'&&a[length]=='S')
	    {
	    	length--;
		}
		else
		{
			length++;
			a[length]=str[i];
		}
	}
	cout<<length;
	return 0;
}

心得体会

常见的问题,字符串处理经过这几次的练习感觉到越来越熟悉了,总体来说不是很困难。

B - 东东转魔方:

问题描述

题目简述

东东有一个二阶魔方,即2×2×2的一个立方体组。立方体由八个角组成。

魔方的每一块都用三维坐标(h, k, l)标记,其中h, k, l∈{0,1}。六个面的每一个都有四个小面,每个小面都有一个正整数。

对于每一步,东东可以选择一个特定的面,并把此面顺时针或逆时针转90度。

请你判断,是否东东可以在一个步骤还原这个魔方(每个面没有异色)。

输入/输出格式

输入格式:
输入的第一行包含一个整数N(N≤30),这是测试用例的数量。

对于每个测试用例, 第 1~4 个数描述魔方的顶面,这是常见的2×2面,由(0,0,1),(0,1,1),(1,0,1),(1,1,1)标记。四个整数对应于上述部分。

第 5~8 个数描述前面,即(1,0,1),(1,1,1),(1,0,0),(1,1,0)的公共面。四个整数 与上述各部分相对应。

第 9~12 个数描述底面,即(1,0,0),(1,1,0),(0,0,0),(0,1,0)的公共面。四个整数与上述各部分相对应。

第 13~16 个数描述背面,即(0,0,0),(0,1,0),(0,0,1),(0,1),(0,1,1)的公共面。四个整数与上述各部分相对应。

第 17~20 个数描述左面,即(0,0,0),(0,0,1),(1,0,0),(1,0,1)的公共面。给出四个整数与上述各部分相对应。

第 21~24 个数描述了右面,即(0,1,1),(0,1,0),(1,1,1),(1,1,0)的公共面。给出四个整数与上述各部分相对应。
输出格式:
对于每个测试用例,魔方如果可以至多 “只转一步” 恢复,输出YES,则输出NO。

友情提示:如果能思考一下解题框架的设计是最好的,一上来就莽很痛苦
友情提示:如果能思考一下解题框架的设计是最好的,一上来就莽很痛苦
友情提示:如果能思考一下解题框架的设计是最好的,一上来就莽很痛苦

样例

输入样例:
4
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6
6 6 6 6 1 1 1 1 2 2 2 2 3 3 3 3 5 5 5 5 4 4 4 4
1 4 1 4 2 1 2 1 3 2 3 2 4 3 4 3 5 5 5 5 6 6 6 6
1 3 1 3 2 4 2 4 3 1 3 1 4 2 4 2 5 5 5 5 6 6 6 6
输出样例:

问题分析

解题思路

暴力做就完了。问题很简单,只问一步,且每次变换只有顺时针和逆时针旋转90°这两种操作。而对一个魔方来说旋转只有3种方向,因此,把这些旋转方法都列出来就好了。并且,如果旋转后能复原,那么,未旋转的两个面一定是同色的且旋转的四个面一定都只有两种颜色且这两种颜色一定分别位于旋转和不旋转的两个棱上,而且要保证旋转之后的面同色。有了以上约束条件即可写出旋转的模拟。同时,如果一开始就已经同色,需要特别判断一下。

参考代码
#include 

using namespace std;

int n;
int m[7][5];

bool rotate1()
{
	if(m[5][1]==m[5][2]&&m[5][2]==m[5][3]&&m[5][3]==m[5][4]&&
	   m[6][1]==m[6][2]&&m[6][2]==m[6][3]&&m[6][3]==m[6][4]&&
	   m[2][1]==m[2][3]&&m[2][2]==m[2][4]&&m[4][1]==m[4][3]&&
	   m[4][2]==m[4][4]&&m[3][1]==m[3][3]&&m[3][2]==m[3][4])
	   {
	   	    if(m[1][1]==m[2][2]&&m[2][1]==m[3][2]&&m[3][1]==m[4][2]&&m[4][1]==m[1][2]) return true;
	   	    if(m[1][1]==m[4][2]&&m[4][1]==m[3][2]&&m[3][1]==m[2][2]&&m[2][1]==m[1][2]) return true;
	   }
	return false;
}

bool rotate2()
{
	if(m[2][1]==m[2][2]&&m[2][2]==m[2][3]&&m[2][3]==m[2][4]&&
	   m[4][1]==m[4][2]&&m[4][2]==m[4][3]&&m[4][3]==m[4][4]&&
	   m[5][1]==m[5][2]&&m[5][3]==m[5][4]&&m[6][1]==m[6][2]&&
	   m[6][3]==m[6][4]&&m[3][1]==m[3][2]&&m[3][3]==m[3][4])
	   {
	   	    if(m[1][1]==m[5][3]&&m[5][1]==m[3][1]&&m[3][3]==m[6][3]&&m[6][1]==m[1][3]) return true;
	   	    if(m[1][1]==m[6][3]&&m[6][1]==m[3][1]&&m[3][3]==m[5][3]&&m[5][1]==m[1][3]) return true;
	   }
	return false;
}

bool rotate3()
{
	if(m[1][1]==m[1][2]&&m[1][2]==m[1][3]&&m[1][3]==m[1][4]&&
	   m[3][1]==m[3][2]&&m[3][2]==m[3][3]&&m[3][3]==m[3][4]&&
	   m[5][1]==m[5][3]&&m[5][2]==m[5][4]&&m[6][1]==m[6][3]&&
	   m[6][2]==m[6][4]&&m[4][1]==m[4][2]&&m[4][3]==m[4][4])
	   {
	   	    if(m[2][1]==m[5][1]&&m[5][2]==m[4][1]&&m[4][3]==m[6][4]&&m[6][1]==m[2][3]) return true;
	   	    if(m[2][1]==m[6][2]&&m[6][1]==m[4][1]&&m[4][3]==m[5][1]&&m[5][2]==m[2][3]) return true;
	   }
	return false;
}

bool special()
{
	for(int i=1;i<=6;i++)
	{
		if(!(m[i][1]==m[i][2]&&m[i][2]==m[i][3]&&m[i][3]==m[i][4])) return false;
	}
	return true;
}

bool solve()
{
	if(m[1][1]==m[1][3]&&m[1][2]==m[1][4]&&m[1][1]!=m[1][2]) return rotate1();
	if(m[1][1]==m[1][2]&&m[1][3]==m[1][4]&&m[1][1]!=m[1][3]) return rotate2();
	if(m[2][1]==m[2][2]&&m[2][3]==m[2][4]&&m[2][1]!=m[2][3]) return rotate3();
	return special();
}

int main()
{
	scanf("%d",&n);
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=6;i++)
	    {
		    for(int j=1;j<=4;j++)
		        scanf("%d",&m[i][j]);
	    }
	    if(solve()) printf("YES\n");
	    else printf("NO\n");
	}
	return 0;
}

心得体会

思考了一个多小时,想怎样存储输入的数据来实现旋转时能用一个公式来表明旋转后的数据之间的关系,然而,怎么想也想不到怎么存储。最后想想觉得其实可以暴力做。第一次遇到这种题,感觉有点无从下手,其实仔细想想就会发现不是很复杂。。。另外,也别忘了物理外挂(自制魔方可还行)。

你可能感兴趣的:(week10——实验(大模拟))