You’ve just been playing a video game in which you had to move a worm through a maze using a joystick. You got the high score, and now you have to enter your name using this joystick. This works as follows.
The initial name displayed on the screen is a string consisting only of ‘A’ characters. Initially the first letter of the string is selected. When you move the joystick forward, the selected letter is changed to the letter that immediately follows it in the alphabet. When you move the joystick backward, the selected letter is changed to the letter that immediately precedes it in the alphabet. The alphabet wraps around, so the letter following ‘Z’ is ‘A’ and the letter preceding ‘A’ is ‘Z’.
Moving the joystick left or right changes the selection one step to the left or right, respectively. The selection also wraps around, so moving left when the first letter is selected will select the last letter and vice versa.
Because you would like to spend as little time as possible on entering your name, you want to know the smallest possible number of joystick moves needed to do this. Given the name you want to enter, write a program that calculates the minimum number of moves needed. You may assume that the length of the initial string is the same as the length of the name that you want to enter. Furthermore, it does not matter which letter is selected at the end of the process.
Input
On the first line a positive integer: the number of test cases, at most 100. After that per test case:
-
One line with a string ss (1≤length(s)≤1000)(1≤length(s)≤1000) consisting of uppercase letters: the name that you want to enter.
Output
Per test case:
-
One line with an integer: the minimum number of joystick moves needed.
Sample Input 1 | Sample Output 1 |
---|---|
2 JEROEN JAN | 56 23 |
题意:t组数据,给你一个字符串,初始字符串长度与给你的字符串长度相等全为‘A’,问你最少需要多少操作将这个初始字符串变成给你的字符串,这个操作分为两种,一是字母的移动,二是位置的移动;
思路:最多的操作就是把这些字母都走一遍,就是每个位置上字母的最小转移数加上字符串长度-1,缩短的距离就是不需要走反而走过的距离,字母为'A'的位置是不需要走的,但是题目又给你了必须从第一个字母先走,这个时候就把字符串中所有连续为'A'的位置记录一下,用l[],r[]数组分别记录左右边界,遍历这些数组取最小值再min(sum+l[i]*2+num-r[i], sum+(num-r[i])*2+l[i]);即从左从右走的最小值。因为不走[ l[i], r[i] ]这个范围,就从第一个位置先到达l[i]还是r[i],走的距离最小。
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e3+100;
string str[maxn];
int a[maxn];
int l[maxn];
int r[maxn];
int vis[maxn];
int main()
{
int n;
cin>>n;
string s;
for(int i=1;i<=n;i++)
{
cin>>s;
int num=s.size();
memset(vis,0,sizeof(vis));
int sum=0;
for(int j=0;j<num;j++)
{
a[j]=min(s[j]-'A','Z'-s[j]+1);
sum+=a[j];
}
int ans=sum+num-1;
int tot=0;
for(int j=1;j<num;j++)
{
if(s[j]=='A'&&!vis[j])
{
vis[j]=1;
l[++tot]=j-1;
int now=j+1;
while(now<num&&s[now]=='A')
{
vis[now]=1;
now++;
}
if(now==num)
{
r[tot]=num;
}
else r[tot]=now;
}
}
for(int j=1;j<=tot;j++)
{
ans=min(ans,min(sum+l[j]*2+num-r[j],sum+(num-r[j])*2+l[j]));
}
cout<<ans<<endl;
}
return 0;
}