题目描述
一个圆环包含26个英文字母,顺时针从a到z排列,有一个指针指向a,每次可以顺时针或逆时针旋转一格。如a顺时针旋转到z,逆时针旋转到b。现在有一个字符串(长度<=10000),请输出要得到这个字符串最少需要旋转的次数。
输入
输入只有一行,是一个字符串。 |
输出
输出最少要转的次数。 |
样例输入
zeus |
样例输出
18 |
思路
综述
这是一道模拟题,没有用到很难的算法。只要理清楚逻辑,就不难做对;
每到一个数思考:
1)顺时针转多少到下一个;
2)逆时针转多少到下一个;
选择小的一个;
循环上述;
优化:两个方向加起来的数一共是26,所以只讨论一个方向即可,如果这个方向转动的次数小于等于13则选择该方向,并且累计步数,反之则累计(26-该方向的步数)
过程
Step1:初始化
每次都从a开始
累加器tot(int)
char now='a';
int tot=0;
Step2:循环开始找字母
下一个字母的选择一共有三种选择方式
选择的原则是,从字母Ascll码小的一个移动到大的一个,计算步数是多少,根据和13的关系来判断是选择哪一个
分支1:下一个字母和目前的字母是相同的
if(now==s[i])continue;
分支2:下一个字母Ascll码大于当前的字母;更新term;
else if(now<s[i]) term=s[i] - now;
分支3:下一个字母Ascll码小于当前的字母;更新term
else if (s[i]<now) term=now-s[i];
判断term和13的关系并且更新tot
if(term<=13) tot+=term;
else tot += (26-term);
更新字母
now = s[i];
总结
面向CSP第三题的大模拟,基本的思路是:先对场景进行建模,对于本题没有用到算法,故只需要模拟出操作流程就可以,但是如本次模拟测试的C题,不仅仅要理清楚逻辑,对场景进行建模,而且要联系到学到的算法上,在真正的CSP 中,大都不会出现只会模拟场景即可的题。
所以如何由具体的场景联系到所学是很重要的,而且需要熟练掌握算法。
代码
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
int i;
cin>>s;
char now='a';
int tot=0;
int term;
for(i=0;i<s.size();i++){
if(now==s[i])continue;
else if(now<s[i]) term=s[i] - now;
else if (s[i]<now) term=now-s[i];
if(term<=13) tot+=term;
else tot += (26-term);
now = s[i];
}
cout<<tot;
}