首页 > 试题广场 >

手机键盘

[编程题]手机键盘
  • 热度指数:31517 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
按照手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次。 如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需要按6下 如果连续两字符在同一个按键上,则两个按键之间需要等一段时间,如ac,在按了a之后,需要等一会儿才能按c。 现在假设每按一次需要花费一个时间段,等待时间需要花费两个时间段。 现在给出一串字符,需要计算出它所需要花费的时间。

输入描述:
一个长度不大于100的字符串,其中只有手机按键上有的小写字母


输出描述:
输入可能包括多组数据,对于每组数据,输出按出Input所给字符串所需要的时间
示例1

输入

bob
www

输出

7
7
#include<iostream>
#include<cstdio>

using namespace std;

int keytab[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
};

int countTheTime(string str){
    int sum=0;
    sum+=keytab[(str[0]-'a')];
    for(int i=1;i<str.size();i++){
        sum+=keytab[(str[i]-'a')];
        if((str[i]-str[i-1])==(keytab[(str[i]-'a')]-keytab[(str[i-1]-'a')])){
            sum+=2;
        }
    }
    return sum;
}

int main(){
    string str;
    while(cin>>str){
        cout<<countTheTime(str)<<endl;
    }
}

发表于 2021-02-20 16:24:25 回复(0)
#include <iostream>
#include <string>
using namespace std;

int keyTable[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};

int main()
{
    string str;
    while(cin>>str)
    {
        int time = 0;
        for(int i=0; i<str.size();i++)
        {
            time += keyTable[str[i]-'a'];
            if(i!=0&&str[i]-str[i-1]==keyTable[str[i]-'a']-keyTable[str[i-1]-'a'])
            {
                time += 2;
            }
        }
        cout<<time<<endl;
    }

    return 0;
}

发表于 2021-01-27 22:19:54 回复(0)
#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 input;
    while (cin >> input) {
        int sum = key[input[0]-'a'];
        for (int i = 1; i <input.size();i++){
            sum += key[input[i] - 'a'];
            if (input[i] - input[i-1]== key[input[i] - 'a'] - key[input[i-1] - 'a'])
                sum += 2;
 
        }
        cout << sum << endl;
    }
 
}

发表于 2020-02-13 11:10:47 回复(0)

  1. #include
  2. using namespace std;
  3. typedef struct Keys
  4. {
  5. char zimu;
  6. int num;
  7. int zone;
  8. }Keys;
  9. int main()
  10. {
  11. int j=0;
  12. int step;
  13. int step1=0;
  14. int step2=0;
  15. int zone1;
  16. int zone2;
  17. char skr[100];
  18. Keys n[26]={{'a',1,2},{'b',2,2},{'c',3,2},{'d',1,3},{'e',2,3},{'f',3,3},{'g',1,4},{'h',2,4},{'i',3,4},{'j',1,5},{'k',2,5},{'l',3,5},{'m',1,6},{'n',2,6},{'o',3,6},{'p',1,7},{'q',2,7},{'r',3,7},{'s',4,7},{'t',1,8},{'u',2,8},{'v',3,8},{'w',1,9},{'x',2,9},{'y',3,9},{'z',4,9}};
  19. cin>>skr;
  20. while(skr[j]!='\0'){j++;}
  21. if(j==0)
  22. {for(int k=0;k<26;k++)
  23. {if(skr[j]==n[k].zimu)
  24. step=n[k].num;
  25. }
  26. }
  27. for(int i=0;i<j;i++)
  28. {for(int k=0;k<26;k++)
  29. {if(skr[i]==n[k].zimu)
  30. step1=step1+n[k].num;
  31. }
  32. }
  33. for(int i=0;i<j-1;i++)
  34. {for(int k=0;k<26;k++)
  35. {if(skr[i]==n[k].zimu)
  36. zone1=n[k].zone;
  37. }
  38. for(int k=0;k<26;k++)
  39. {if(skr[i+1]==n[k].zimu)
  40. zone2=n[k].zone;
  41. }
  42. if(zone1==zone2) step2=step2+2;
  43. }
  44. step=step1+step2;
  45. cout<<step<<endl;
  46. return 0;
  47. }

发表于 2019-02-17 12:26:11 回复(0)
#把键盘贴出来,一个记录结果,一个记录上一个键盘位的下标(初始为-1)
#如果在键盘里找到了该字符,则结果加上该字符在该键的下标+1,
#如果该字符所在键下标和上一个相等,结果+2,记录当前键下标
while True:
    try:
        keyboard = ['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
        string = input()
        result,lastIndex = 0,-1
        for i in range(len(string)):
            for j in range(len(keyboard)):
                if keyboard[j].find(string[i]) != -1:
                    result += keyboard[j].find(string[i]) + 1
                    if lastIndex == j:          #如果和上一个字符在同一个键盘位+2
                        result += 2
                    lastIndex = j
                    break
        print(result)
    except Exception:
        break

编辑于 2018-10-11 23:39:58 回复(0)
那我就这么做吧。。
import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext())
        {
            String orig = sc.next();
            int total = 0;
            for (int i = 0; i < orig.length(); i++)
            {
                char current = orig.charAt(i);
                int button = toNum(current) / 10;
                int times = toNum(current) % 10;
                total += times;
                if (i < orig.length() - 1 && toNum(orig.charAt(i + 1)) / 10 == button)
                    total += 2;
            }
            System.out.println(total);
        }
        sc.close();
    }
    
    public static int toNum(char c)
    {
        switch(c)
        {
        case 'a': return 21;
        case 'b': return 22;
        case 'c': return 23;
        case 'd': return 31;
        case 'e': return 32;
        case 'f': return 33;
        case 'g': return 41;
        case 'h': return 42;
        case 'i': return 43;
        case 'j': return 51;
        case 'k': return 52;
        case 'l': return 53;
        case 'm': return 61;
        case 'n': return 62;
        case 'o': return 63;
        case 'p': return 71;
        case 'q': return 72;
        case 'r': return 73;
        case 's': return 74;
        case 't': return 81;
        case 'u': return 82;
        case 'v': return 83;
        case 'w': return 91;
        case 'x': return 92;
        case 'y': return 93; 
        case 'z': return 94;
        }
        return 250+38+2;  // 纯搞笑
    }
}

发表于 2018-08-05 10:52:17 回复(0)
//此方法思路为,创建String数组把按键枚举出来,利用String.indexOf()
//构造方法计算时间和判断是否在同一按键上
import java.util.Scanner;
public class Main{
//枚举按键,装入数组     public static String[] str = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            char[] ch = sc.nextLine().toCharArray();  //接收键盘输入
            int times = cal(ch[0]);              //用tims接收计算第一个字符所需时间段
            for(int i=1;i<ch.length;i++){       //从第二个字符开始计算时间段
                if(judge(ch[i-1],ch[i]) > 0){   //判断连续两个字符是否在同一按键上
                    times+=2;                  //同一按键则时间段加2
                }
                times =cal(ch[i])+times;        //计算字符所需时间段
            }
            System.out.println(times);          //打印最终结果
        }
    }
 //创建cal()方法,计算按char c按键所需时间,返回index+1为按键所需时间段
    public static int cal(char c){
        int index = -1;
        for(int i=0;i<str.length;i++){
            index = str[i].indexOf(c);
            if(index != -1){
                return index+1;
            }
        }         return 0;
    }
 //判断字符char a和字符char b是否在同一按键上,是则返回1,否则返回-1
    public static int judge(char a,char b){
        int i=0,j=0;                    //用i记录a字符的按键位置,j记录b字符的按键位置
        for (; i < str.length; i++) {
            if(str[i].indexOf(a) != -1){
                break;
            }         }
        for (; j < str.length; j++) {
            if(str[j].indexOf(b) != -1){
                break;
            }         }
        if(i==j){                     //判断a字符和b字符是否在同一按键上
            return 1;
        }         return -1;
    }
}

编辑于 2018-08-04 07:31:30 回复(0)
#include<iostream>
#include<string>
#include<math.h>
using namespace std;
//用数组来记录字母所处的按键,空间换时间
int keyboard[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
bool isOnSampleButton(int i, string str)
{
    if(keyboard[str[i] - 'a'] == keyboard[str[i+1] - 'a'])
        return true;
    else
        return false;
}
int main()
{
    string str;
    int count = 0;
    while(cin >> str)
    {
        count = 0;
        for(int i = 0; i < str.length(); i++)
        {
            char c = str[i];
            if(c == 'a' || c == 'd' || c == 'g' || c == 'j' || c == 'm' || c == 'p' || c == 't' || c == 'w')
                count++;
            else if(c == 'b' || c == 'e' || c == 'h' || c == 'k' || c == 'n' || c == 'q' || c == 'u' || c == 'x')
                count+=2;
            else if(c == 'c' || c == 'f' || c == 'i' || c == 'l' || c == 'o' || c == 'r' || c == 'v' || c == 'y')
                count+=3;
            else if(c == 's' || c == 'z')
                count+=4;
            if((i < str.length() - 1) && isOnSampleButton(i, str))//此处判断是否在同一按键上,与前几个if不是并列关系
                count+=2;
        }
        cout << count << endl;
    }
    return 0;
}

发表于 2018-07-24 00:22:41 回复(0)
对比其他大神的代码,感觉自己想太多了。。。
具体代码:
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<iterator>
using namespace std;

int count(char);
int count(char, char);
vector<set<char>> alphabet;
const int chCnt[] =
    { 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 };
int main() {
    alphabet.push_back(set<char>{ 'a', 'b', 'c' });
    alphabet.push_back(set<char>{ 'd', 'e', 'f' });
    alphabet.push_back(set<char>{ 'g', 'h', 'i' });
    alphabet.push_back(set<char>{ 'j', 'k', 'l' });
    alphabet.push_back(set<char>{ 'm', 'n', 'o' });
    alphabet.push_back(set<char>{ 'p', 'q', 'r', 's' });
    alphabet.push_back(set<char>{ 't', 'u', 'v' });
    alphabet.push_back(set<char>{ 'w', 'x', 'y', 'z' });

    string temp;
    vector<string> words;
    while (cin >> temp) words.push_back(temp);
    for (vector<string>::iterator beg = words.begin();
        beg != words.end();++beg) {
        int tempCnt = 0;
        for (string::iterator beg = temp.begin();
            beg != temp.end();++beg)
            tempCnt += count(*beg);
        for (string::iterator iter1 = temp.begin(),
            iter2 = ++temp.begin();iter2 != temp.end();
            ++iter1, ++iter2)
            tempCnt += count(*iter1, *iter2);
        cout << tempCnt << endl;
    }
    return 0;
}
inline int count(char c) {
    return chCnt[c - 97];
}
int count(char lhs, char rhs) {

    vector<set<char>>::iterator lIndex, rIndex;
    for (vector<set<char>>::iterator beg = alphabet.begin();
        beg != alphabet.end();++beg) {
        if (beg->find(lhs) != beg->end())
            lIndex = beg;
        if (beg->find(rhs) != beg->end())
            rIndex = beg;
    }
    bool flag = (lIndex == rIndex);
    if (flag)
        return 2;
    else return 0;
}


发表于 2018-07-01 14:18:07 回复(0)
#include<iostream>
#include<string.h>
using namespace std;
int main(){
    string str;
    int pos[26]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8};
    int pos1[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};
    while(cin>>str){
        int len=str.size();
        int sum=pos1[str[0]-'a'];
        for(int i=1;i<len;i++){
            if(pos[str[i]-'a']==pos[str[i-1]-'a']){
                sum=sum+pos1[str[i]-'a']+2;
            }
            else{
                sum=sum+pos1[str[i]-'a'];
            }
        }
        cout<<sum<<endl; 
    }
    return 0;
}

发表于 2018-04-27 00:29:01 回复(0)
#include<stdio.h>
int main()
{
    char a[100],t[8][5]={"abc ","def ","ghi ","jkl ","mno ","pqrs","tuv ","wxyz"};
    int i,pos[100],j,k,count[100],sum;
    while(scanf("%s",a)!=EOF)
    {
        i=0;
        sum=0;
        while(a[i]!='\0')
        {
            for(j=0;j<8;j++)
                for(k=0;k<4;k++)
                if(t[j][k]==a[i])
                 {
                     pos[i]=j;
                     count[i]=k+1;
                     j=8;
                     i++;
                     break;
                 }
        }
        i=0;
        while(a[i]!='\0')
           if(a[i+1]!='\0')
                if(pos[i]==pos[i+1])
           {
               sum=sum+count[i]+2;
               i++;
           }
                else {sum+=count[i];i++;}
           else  {sum+=count[i];i++;}
        printf("%d\n",sum);
    }
    return 0;
}
发表于 2018-01-13 16:26:37 回复(0)
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    int i,j,k,sum,now,before,len;
    char string[200];
    char a[8][4]={{'a','b','c'},{'d','e','f'},{'g','h','i'},{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};
    
    while(scanf("%s",string)!=EOF)
    {
        len=strlen(string);
        sum=k=0;
        while(k<len)
        {
            for(i=0;i<8;i++)
            {
                for(j=0;j<4;j++)
                {
                        if(string[k]==a[i][j])
                        {
                            now=i;
                            i=8;
                            k++;
                            break;
                        }
                }
            }
                if(k!=1&&before==now)
                {
                    sum+=2;
                    sum+=(j+1);
                }
                else
                {
                    sum+=(j+1);
                    before=now;
                }
        }
        printf("%d\n",sum);
    }
    return 0;
}

发表于 2018-01-12 19:28:41 回复(0)
java版本
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int[] a= new int[]{
                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
        };

        int[] keys=new int[]{
                1,1,1,
                2,2,2,
                3,3,3,
                4,4,4,
                5,5,5,
                6,6,6,6,
                7,7,7,
                8,8,8,8
               };

        while (in.hasNext()) {
            String str=in.nextLine();

            int times=0;
            char pre;

            times+=a[str.charAt(0)-'a'];
            pre=str.charAt(0);

            for (int i=1;i<str.length();i++){
                if (keys[str.charAt(i)-'a']==keys[pre-'a'])
                    times+=2;
                times+=a[str.charAt(i)-'a'];
                pre=str.charAt(i);
            }

            System.out.println(times);

        }

        in.close();
    }
}


发表于 2017-07-18 18:16:55 回复(0)
#include <iostream>
using namespace std;
int main(){
    string a;
    while(cin>> a)
    {
        int time=0;
        int lastword=26;//上个按键记录
        int word=0;
        int ay[27]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8,9};
       //字母对应按键,第27位的9用于表示第一次“上个按键”没有记录
        for(int i=0;i<a.size();i++)
        {
            word=(int)a.at(i)-97;
            if(ay[word]==ay[lastword])time+=2;//按相同键
            for(int i=0;word-i>=0&&ay[word-i]==ay[word];i++)time++;//按键所需次数           
            lastword=word;
        }       
        cout<< time << endl;
    }
    return 0;
}
 //清晰简明
发表于 2017-02-25 11:35:11 回复(0)
首先说一下,题目的结果bcb是错误的。对应的数值应当是11.然后对键盘不熟悉也坑了我一把,只能打开手机参考键盘写题目了。
#include <iostream>
#include <string.h>

#define max 102

char str[max];
using namespace std;

int tian[]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8};
int xia[]={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};
bool iswait(char* a,int i){
    if(i==0)return false;
    if(tian[a[i]-'a']==tian[a[i-1]-'a'])return true;
    return false;
}

int main()
{
    int time;
    while(cin>>str){
        time = 0;
        int length =strlen(str);
        for(int i = 0;i < length;i++){
            if(iswait(str,i)){
                time+=2;
                //cout<<"add2"<<endl;
            }
            time+=xia[str[i]-'a'];
            //cout<<"add"<<xia[str[i]-'a']<<endl;
        }
        cout<<time<<endl;
    }
    return 0;
}

发表于 2016-04-07 21:19:04 回复(2)
其实只需要一个数组就够用了啊。用key顺序记录26个字母按键次数,
然后判断两个字母是否在同一个按键上,如果在同一个按键上,那么下标差(字母间距)
就等于按键次数差。
#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;
    }
}

发表于 2018-05-20 16:47:43 回复(25)
        本题要计算的时间需要考虑两种情况:1、相邻的两个字母不在同一个按键上,这时在输入后一个字母时就不用等待;2、相邻的两个字母在一个按键上,那么在输入后一个字母的时候就需要等待两个单位时间。
        首先,使用一个大小为 26 数组 alpha 来记录每个字母在输入时所需要的时间;再次使用另外一个大小也为 26 的数组 keys 来对字母进行按键分组, 以确定在同一个按键上的字母。
        在依次扫描输入字符串的时候需要与前一个字符进行对比,以确定是否需要等待,这就需要一个记录前一个字符的变量。在访问上面两个数组的时候使用 ascii 码进行即可。
        具体代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
intmain() {
    intalpha[26] = {
        1, 2, 3,    // a, b, c
        1, 2, 3,    // d, e, f
        1, 2, 3,    // g, h, i
        1, 2, 3,    // j, k, l
        1, 2, 3,    // m, n, o
        1, 2, 3, 4, // p, q, r, s
        1, 2, 3,    // t, u, v
        1, 2, 3, 4 // w, x, y, z
    }; //存储输入每个小写字母时需要的时间
 
    intkeys[26] = {
        1, 1, 1, // a, b, c
        2, 2, 2, // d, e, f
        3, 3, 3, // g, h, i
        4, 4, 4, // j, k, l
        5, 5, 5, // m, n, o
        6, 6, 6, 6, // p, q, r, s
        7, 7, 7, // t, u, v
        8, 8, 8, 8// w, x, y, z
    }; // 对字母进行分组,以确定在一个按键上面的字母
 
    charpre; // 存储前一个字母
    charstr[110];
    inttimes; //所需要的输入次数
 
    while(scanf("%s", str) != EOF) {
        times = 0;
        inti;
        pre = '#';
        for(i=0; i<strlen(str); i++)  {
            if(keys[pre-97] == keys[str[i]-97]) {
                times += 2; //相同字母需要等待的时间
            }
            times += alpha[str[i] - 97];
            pre = str[i];
        }
        printf("%d\n", times);
    }
 
    return0;
}
编辑于 2016-01-01 16:38:17 回复(7)
为什么说这道题目***呢,首先键盘上abc就不在1键位上;
再次说为什么这道题目***呢,因为键盘上pqrs和wxyz在同一个键位上,但是题目没说呀,老子****的3个一组去做了半天;
最后一次说为什么这道题目***呢,因为有人告诉我这种排列方法是常识!!!
#inlcue<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
map<char, int> myMap;
int num = 1;
char a = 'a';
while ('z'>a){
myMap[a++] = num*10+1;
if(a!='z')
myMap[a++] = num*10+2;
if (a != 'z')
myMap[a++] = num*10+3;
if (a == 's'||a == 'z')
myMap[a++] = num * 10 + 4;
num++;
}
string temp;
while (cin >> temp){
int sum = 0;
int pre = -1;
for (auto& e : temp){
int key = myMap[e] / 10;
if (key!= pre)//前后在不同键位,需等待一次
sum += 0;
else//同一键位,需等待多一次
sum += 2;
sum += myMap[e] % 10;
pre = key;
}
cout << sum << endl;
}
}

编辑于 2017-04-26 21:43:54 回复(22)
//话说辅助数组真的省很多事儿
#include<iostream>
#include<cstring>
using namespace std;
int helper1[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 };
int helper2[26] = { 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8 };
int main() {
	char ch[101];
	while (cin >> ch) {
		int total = helper1[ch[0] - 'a'], last = helper2[ch[0] - 'a'];//总时间
		for (int i = 1; i<strlen(ch); i++) {
			int temp = helper2[ch[i] - 'a'];
			total += helper1[ch[i] - 'a'];
			if (temp == last)
				total += 2;
			last = temp;
		}
		cout << total << endl;
	}
}

发表于 2020-01-11 21:39:04 回复(0)
我想关键就在于如何去判断相邻两个字符是否属于同一按键内,根据高赞作者 som8body 与王道书的内容,字母在字符串中本身的间距等于按键次数之差,则属于同一按键,真是精妙的想法鸭!
#include<iostream>
#include<cstdio>
using namespace std;
//数据预处理
const int keytab[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};
int main(){
    string str;
    while(cin>>str){
    	int time = 0;
        for(int i=0; i<str.length(); i++){
            time += keytab[str[i]-'a'];
            if(i!=0&&(str[i]-str[i-1]==keytab[str[i]-'a']-keytab[str[i-1]-'a'])){
                time += 2;
            }
        }
        cout<<time<<endl;
    }
    return 0;
}

发表于 2020-02-12 11:50:50 回复(0)

问题信息

难度:
204条回答 18370浏览

热门推荐

通过挑战的用户

查看代码