程序设计思维(CSP模拟题) 咕咕东的奇遇

题目

题目描述
咕咕东是个贪玩的孩子,有一天,他从上古遗迹中得到了一个神奇的圆环。这个圆环由字母表组成首尾相接的环,环上有一个指针,最初指向字母a。咕咕东每次可以顺时针或者逆时针旋转一格。例如,a顺时针旋转到z,逆时针旋转到b。咕咕东手里有一个字符串,但是他太笨了,所以他来请求你的帮助,问最少需要转多少次。

输入格式
输入只有一行,是一个字符串。

输出格式
输出最少要转的次数。

样例输入
zeus

样例输出
18

数据点 字符串长度
1, 2 小于等于10
3, 4, 5 小于等于100
6, 7, 8, 9, 10 小于等于10000

思路

如图:
在这里插入图片描述
图中红色的为字符,橙色的为ASCII码(十进制),蓝色的为该字符的编号:0(A)、1(B)、2(C)、……、25(Z)。
在这里插入图片描述
例如从k开始转:
顺时针转:1次到l、2次到m、3次到n、……、13次到x;
逆时针转:1次到j、2次到i、3次到h、……、13次到x;
其他的依次类推。
可以发现,从字符c1(字符编号记为c1)转到字符c2(字符编号记为c2)需要的转数k:

① k = |c1 - c2|(|c1 - c2|≤13)
② k = 26 - |c1 - c2|(|c1 - c2|>13)

所以,根据公式将字符之间的转数累加即可。

代码

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int index(char a)
{
	return a - 'a';
}

int distance(char c1, char c2)
{
	int dif = abs(index(c1) - index(c2));
	if (dif <= 13)
		return dif;
	else
		return 26 - dif;
}

int main()
{
	string str;
	cin >> str;

	str = "a" + str;

	int cnt = 0;

	for (int i = 0; i < str.length() - 1; i++) {
		// cout << str[i] << " " << str[i + 1] << ":" << distance(str[i], str[i + 1]) << endl;
		cnt += distance(str[i], str[i + 1]);
	}

	cout << cnt << endl;

	return 0;
}

在模拟比赛时,由于时间有限,而且我想了一定的时间都没想出公式,所以直接将全部情况枚举在了一个26*26的二维数组里。这个枚举很简单,对于每一行(第一行除外)只需把上一行的复制一下,再将最后一个数放在最前面就可以了,手速快一点的话五分钟以内就可以完成。
我觉得,如果一时找不出公式,且枚举困难不大的话,是可以考虑使用枚举的,以节约时间。

模拟比赛时的代码

#include <iostream>
#include <string>

using namespace std;

int M[26][26] = {
	{0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1},
	{1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2},
	{2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3},
	{3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4},
	{4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5},
	{5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6},
	{6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7},
	{7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8},
	{8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9},
	{9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10},
	{10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11},
	{11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,12},
	{12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13},
	{13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12},
	{12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11},
	{11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10},
	{10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9},
	{9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8},
	{8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7},
	{7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6},
	{6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5},
	{5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4},
	{4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3},
	{3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1,2},
	{2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,1},
	{1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0}
};

// A(0)~Z(25)

void printMatrix(int n)
{
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cout << M[i][j] << " ";
		}
		cout << endl;
	}
}

int index(char a)
{
	return a - 'a';
}

int main()
{	
	//printMatrix(26);

	string str;
	cin >> str;

	str = "a" + str;

	//cout << str << endl;
	//cout << str.length() << endl;

	int cnt = 0;

	for (int i = 0; i < str.length() - 1; i++) {
		//cout << str[i] << " " << str[i + 1] << ":" << M[index(str[i])][index(str[i + 1])] << endl;
		cnt += M[index(str[i])][index(str[i + 1])];
	}

	cout << cnt << endl;

	return 0;
}
发布了12 篇原创文章 · 获赞 0 · 访问量 122

猜你喜欢

转载自blog.csdn.net/weixin_43826681/article/details/104988613