P9856 题解
很明显的一道模拟题,需要注意的点如下:
-
打完字符串后需要按下
enter键。 -
字符串读入需要使用
getline(),因为有输入有space键。
Step 1:初始化键盘
这一步我是用两个 map 来存储字符的位置,根据题意写出构造代码。
void keyboard()
{
for(char i = 'A';i <= 'Z';i++)
{
x[i] = 1+(i-'A')/6; // x[] 表示在第几行。
y[i] = (i-'A')%6+1; // y[] 表示在第几个。
}
x[' '] = x['-'] = x['.'] = 5;
y[' '] = 3, y['-'] = 4, y['.'] = 5;
}
注:enter 键因为不好表示没有计入数组,也不会多次使用。
Step 2:计算距离
这里使用直角距离,也就是计算两点横向距离与纵向距离之和。
// pntx 与 pnty 表示当前已打完字符的位置
int dis(int x,int y) // x 与 y 表示将要打的字符的位置
{
return abs(x-pntx)+abs(y-pnty); // 注意绝对值
}
Step 3:模拟操作
根据题意模拟即可。
int main()
{
keyboard(); // 初始化函数写完不要忘记调用!
getline(cin,s); // 注意点2。
for(int i = 0;i < s.length();i++)
{
ans += dis(x[s[i]],y[s[i]]); // 一个一个敲下字符。
pntx = x[s[i]], pnty = y[s[i]]; // 更新当前位置。
}
ans += dis(5,6); // 注意点1。
cout << ans;
return 0;
}
过程就是这么多,下面给一份完整代码。
#include <iostream>
#include <cmath>
#include <map>
#define big long long
using namespace std;
map <char,big> x,y;
big id=1,pntx=1,pnty=1,ans;
string s;
void keyboard()
{
for(char i = 'A';i <= 'Z';i++)
{
x[i] = 1+(i-'A')/6;
y[i] = (i-'A')%6+1;
}
x[' '] = x['-'] = x['.'] = 5;
y[' '] = 3, y['-'] = 4, y['.'] = 5;
}
big dis(big x,big y)
{
return abs(x-pntx)+abs(y-pnty);
}
int main()
{
keyboard();
getline(cin,s);
for(big i = 0;i < s.length();i++)
{
ans += dis(x[s[i]],y[s[i]]);
//printf("to %c: %lld\n",s[i],dis(x[s[i]],y[s[i]]));
pntx = x[s[i]], pnty = y[s[i]];
}
ans += dis(5,6);
cout << ans;
return 0;
}