Timus 1567. SMS-spam

本文讲述了一位名叫Petr的学生如何利用非法获取的手机号码清单,为办公室业主提供短信广告服务,并详细解释了计算短信费用的简单算法。通过键盘按键数量来决定收费,从而实现成本计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Timus 1567. SMS-spam 要求计算手机短信的收费情况。


Timus 1567. SMS-spam

Time Limit: 1.0 second
Memory Limit: 64 MB

Petr, a student, decided to start his own business. He offers SMS advertising services to the business owners renting offices in the newly built “Prisma” tower. If an office owner wants to use the service, he devises a slogan and Petr texts it from his personal phone to thousands of Ekaterinburg citizens (he already bought the pirated list of mobile phone numbers). The cost of each slogan sent is a sum of costs of each character typed. Cost of an individual character is determined according to a very simple scheme: each tap at the phone's keyboard costs 1 rouble.

Petr's phone doesn't support sophisticated text input technologies, such as T9, and only the english alphabet can be used.

1
abc
2
def
3
ghi
4
jkl
5
mno
6
pqr
7
stu
8
vwx
9
yz
 0
.,!
#
_

The “_” character in the table denotes whitespace. If you want to, for example, type “a”, you need to press the “1” button once. To type “k”, you press “4” twice. To type “!”, press “0” three times.

Petr has to apply this simple algorithm to calculate the cost of every slogan he sends. However, Petr is a very busy man (and, as a matter of fact, doesn't bother to learn arithmetics, because he's a Philosophy student). You just have to help Petr, you are his best friend after all.

Input

The single line of input contains the slogan. Slogan consists of words, spaces, commas, full stops and exclamation marks. All the words consist of lowercase english letters. Slogan can't be longer than 1000 characters.

Output

Output a single number representing the cost of the given slogan, according to Petr's pricing.

Sample
inputoutput
pokupaite gvozdi tolko v kompanii gvozdederov i tovarischi!114

Problem Author: Denis Musin
Problem Source: The XIIth USU Programing Championship, October 6, 2007


题意

这道题目是讲俄罗斯一位学生 Petr 的创业故事。Petr 购买了数千个叶卡特琳堡市民的手机号码,以便提供发送垃圾短信服务(想不到俄罗斯也有出售非法的手机号码清单,也有垃圾短信)。Petr 是通过他的手机来发送短信的,按照他的手机键盘(跟我们常见的手机键盘的布局有些不同),“a”需要按“1”键一次,“k”需要按“4”键两次,“!”需要按“0”键三次。Petr 是按照按键次数来收费的,每一次按键收费一卢布。我们的任务就是写一个程序计算每条短信应该收多少钱。

解答

下面是 C# 源程序:

01:  using System;
02:  using System.Collections.Generic;
03:  
04:  namespace Skyiv.Ben.Timus
05:  {
06:    // http://acm.timus.ru/problem.aspx?space=1&num=1567
07:    sealed class T1567
08:    {
09:      static void Main()
10:      {
11:        var dict = GetPrice();
12:        var sum = 0;
13:        foreach (var c in Console.ReadLine()) sum += dict[c];
14:        Console.WriteLine(sum);
15:      }
16:      
17:      static Dictionary<char, int> GetPrice()
18:      {
19:        var dict = new Dictionary<char, int>();
20:        for (var i = 0; i < 4; i++) dict.Add(".,! "[i], (i % 3) + 1);
21:        for (var i = 0; i < 26; i++) dict.Add((char)(i + 'a'), (i % 3) + 1);
22:        return dict;
23:      }
24:    }
25:  }

上述程序首先构造一个不同字符的收费表,然后再计算该收的费用。注意如果输入中出现了不在收费表的字符,该程序将抛出 KeyNotFoundException。但这是ACM题,我们只要按照题意写程序就行,也就是按照契约编程,不用考虑意外的输入。

下面是 C 源程序:

01:  // http://acm.timus.ru/problem.aspx?space=1&num=1567
02:  
03:  #include <stdio.h>
04:  
05:  int getPrice(char c)
06:  {
07:    if (c == '.' || c == ' ') return 1;
08:    if (c == ',') return 2;
09:    if (c == '!') return 3;
10:    return 1 + (c - 'a') % 3;
11:  }
12:  
13:  int main()
14:  {
15:    int i, sum = 0;
16:    char buf[1001];
17:    gets(buf);
18:    for (i = strlen(buf) - 1; i >= 0; i--)
19:      sum += getPrice(buf[i]);
20:    printf("%d\n", sum);
21:    return 0;
22:  }

上述程序中的 getPrice 函数用来计算每个字符的收费。注意上述程序中的 gets 函数是不安全的,如果输入超出 1000 个字符,将造成缓冲区溢出。同样由于这是 ACM 题,所以不用担心。

下面是 C++ 源程序:

01:  // http://acm.timus.ru/problem.aspx?space=1&num=1567
02:  
03:  #include <iostream>
04:  #include <string>
05:  
06:  using namespace std;
07:  
08:  int getPrice(char c)
09:  {
10:    if (c == '.' || c == ' ') return 1;
11:    if (c == ',') return 2;
12:    if (c == '!') return 3;
13:    return 1 + (c - 'a') % 3;
14:  }
15:  
16:  int main()
17:  {
18:    string buf;
19:    getline(cin, buf);
20:    int sum = 0;
21:    for (string::iterator it = buf.begin(); it < buf.end(); it++)
22:      sum += getPrice(*it);
23:    cout << sum << endl;
24:    return 0;
25:  }

上述程序和 C 程序基本上是一样的,不过 getline 函数是安全的。

下面是 F# 源程序:

01:  // http://acm.timus.ru/problem.aspx?space=1&num=1567
02:  
03:  let getPrice c =
04:    match c with
05:    | '.' | ' ' -> 1
06:    | ',' -> 2
07:    | '!' -> 3
08:    | x -> 1 + (int x - int 'a') % 3
09:  
10:  let pricing str = str |> Seq.map getPrice |> Seq.sum
11:    
12:  System.Console.ReadLine() |> pricing |> printfn "%d"

可以看出 F# 程序最简单明了,Seq.map 根据 getPrice 来计算每个字符的收费,再用 Seq.sum 来求和。


返回目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值