P9856 题解

· · 题解

很明显的一道模拟题,需要注意的点如下:

  1. 打完字符串后需要按下 enter 键。

  2. 字符串读入需要使用 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;
}