前言
本篇题解来自洛谷,原作者:MengTian1120,原文:https://www.luogu.com.cn/article/te1brr0l。
本篇题解的解题方法为:模拟。
题目大意
题目还是比较好理解的。
题目
你知道如何用英文读出电话号码吗?现在让我来告诉你。
例如,在中国,电话号码是 位数字,如:。有人将号码划分为 -- 的格式,即 ;而有人则将号码划分为 -- 的格式,即 。不同的格式会导致读出这些数字的方式不同:
读作 one five zero one double two three three triple four。
读作 one five zero one double two double three triple four。
现在问题来了:
给定一个电话号码列表以及划分格式,请输出这些号码的正确读法。
规则:
单个数字只需分开读出。
连续 个相同数字使用 double。
连续 个相同数字使用 triple。
连续 个相同数字使用 quadruple。
连续 个相同数字使用 quintuple。
连续 个相同数字使用 sextuple。
连续 个相同数字使用 septuple。
连续 个相同数字使用 octuple。
连续 个相同数字使用 nonuple。
连续 个相同数字使用 decuple。
连续超过 个相同数字则全部分开读出。
解题思路
根据题目要求模拟即可,没有什么思维难度,做法也比较好想。
代码实现
这里有一个技巧,判断重复字符个数的时候,不用一个一个 if,开一个 string 数组 ,其中,
表示连续 个相同数字使用的缩写。
同时,数字对应的英文单词也可以开一个 string 数组 ,其中
表示数字 对应的英文单词。
string num[]={"zero","one","two","three","four","five","six","seven","eight","nine"};
string mp[]={"","","double","triple","quadruple","quintuple","sextuple","septuple","octuple","nonuple","decuple"};
这道题还有一个难点,就是对字符串的处理。
难点在于如何按照给定的格式对电话号码进行分组,并在每个分组内正确处理连续相同数字的读法。
输入的格式字符串如 3-4-4,需要将其解析为若干个数字段。这里采用的方法是在原字符串末尾加上一个 -,然后遍历每个字符:
- 遇到数字字符时,累加到当前长度变量 中:
len=len*10+(c-'0')。 - 遇到
-时,表示一个分组结束,此时 的值就是该分组的长度。
f+='-';//末尾加分号,方便处理最后一段
for(char c:f){
if(c != '-') len=len*10+(c-'0');
else{
//处理长度为 len 的分组
len=0;//一定要记得重置!
}
}
对于每个长度为 的分组,需要从电话号码字符串 中取出对应的 个字符进行处理。这里使用变量 记录当前处理到的位置。
在每个分组内,采用双指针的方法统计连续相同数字的个数:
for(int i=0;i<len;){
char cur=s[pos+i];
int cnt=1;
//向后统计有多少个连续且相同字符
while(i+cnt<len && s[pos+i + cnt]==cur) cnt++;
//根据 cnt 的值决定如何去读
i+=cnt;//跳过已经处理完的字符
}
根据统计出的连续个数 ,按照题目规则输出:
| 读法 | |
|---|---|
| 直接读数字 | |
使用 double ~ decuple + 数字 |
|
| 单独读出 |
超过 个相同数字全部单读,这是因为题目给出的特殊读法只支持到 decuple。
AC 代码
#include <bits/stdc++.h>
using namespace std;
string num[]={"zero","one","two","three","four","five","six","seven","eight","nine"};
string mp[]={"","","double","triple","quadruple","quintuple","sextuple","septuple","octuple","nonuple","decuple"};
int main(){
int T;
cin>>T;
for(int t=1;t<=T;t++){
string s,f,ans;
cin>>s>>f;
f+='-';
int pos=0,len=0;
for(char c:f){
if(c!='-') len=len*10+(c-'0');
else{
for(int i=0;i<len;){
if(pos+i>=s.size()) break;
char cur=s[pos+i];
int cnt=1;
while(i+cnt<len && pos+i+cnt<s.size() && s[pos+i+cnt]==cur) cnt++;
if(cnt>=2 && cnt<=10){
if(!ans.empty()) ans+=" ";
ans+=mp[cnt]+" "+num[cur-'0'];
}
else{
for(int j=0;j<cnt;j++){
if(!ans.empty()) ans+=" ";
ans+=num[cur-'0'];
}
}
i+=cnt;
}
pos+=len;
len=0;
}
}
cout<<"Case #"<<t<<": "<<ans<<'\n';
}
return 0;
}
后记
这是本蒟蒻的第 篇题解,求过。
给个赞再走呗!
暂无评论