思路
先贴一下 26 个字母的分布:
ABC | DEF | |
---|---|---|
GHI | JKL | MNO |
PQRS | TUV | WXYZ |
规则很清晰,就是字母在哪一块的第几个位置就按几下,相邻的字母如果在同一块上面就需要等待 2 个时间段,所以我们需要做的第一步其实是应该存一下每个字母所在的位置,然后就很容易求了。
#include<iostream> #include<vector> using namespace std; class Block{ public: int block; int pos; public: Block(int block, int pos) : block(block), pos(pos){} }; int getCost(string s, vector<Block>& chars){ int cnt = 0, n = s.size(); for(int i = 0; i < n; i ++){ cnt += chars[s[i] - 'a'].pos; if(i > 0 && chars[s[i] - 'a'].block == chars[s[i - 1] - 'a'].block) cnt += 2; } return cnt; } int main(){ string s; vector<Block> chars; // 初始化字母的位置 for(int i = 0; i < 18; i ++) chars.emplace_back(i / 3, i % 3 + 1); chars.emplace_back(5, 4); chars.emplace_back(6, 1); chars.emplace_back(6, 2); chars.emplace_back(6, 3); chars.emplace_back(7, 1); chars.emplace_back(7, 2); chars.emplace_back(7, 3); chars.emplace_back(7, 4); while(cin >> s){ cout << getCost(s, chars) << endl; } return 0; }
更简单的做法,这个就不用存每个字母的位置了,因为如果两个字母在一个按钮里面,那个 pos 肯定是连续的,所以字母的距离和 pos 之差应该相等。
#include<iostream> #include<string> using namespace std; int main(){ int key[26] = {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4}; string str; while(cin >> str){ int count = key[str[0]-'a']; for(int i = 1; i < str.size(); i ++){ count += key[str[i]-'a']; if(key[str[i]-'a']-key[str[i-1]-'a'] == str[i]-str[i-1])//判断是否在同一个按键上 count+=2; } cout << count << endl; } return 0; }