一道字符串+模拟的洛谷橙题,题面如下:
![](https://i-blog.csdnimg.cn/blog_migrate/e4f6b4e2edc73fc7408d3904e59ad9e9.png)
不得不说,这道题的样例真滴良心^_^,帮我们把所有的坑都填上力!那么剩下就靠自己稳步前进啦!
解题:
读取信息
题目给出的数据可以看作一段一段的字符串,不妨用vector<string>容器储存,如下方法输入:
vector<string>v;
string s;
while(cin>>s)v.push_back(s);
注:本题如果用getline(),可能会导致判题出错!
字符串的比较
为了判断每一段字符分别是什么,一定避免不了字符串之间的比较啦~
c++的string已经重载了==运算符,我们便可通过如下方法简单地比较字符串是否相等:
string s
if ( s == "one" )
量词
本题的量词有“hundred”、“thousand”、“million”
对于类似eight thousand six hundred的输入,想要得到8600的答案输出,我们必须对量词前的数据加以记录,再使该数据乘上对应的量,加入到答案ans中,再将memo置0,
例:
读取字串eight时,记录memo=8,
读取thousand时,8×1000=8000,ans+=8000,memo=0;
读取字串six时,记录memo=6,
读取hundred时,6×100=600,ans+=600,memo=0;
经过上述结果,我们便轻松地得到正确答案ans=8600。
然鹅,橙题并不应该这么简单……
样例4:
eight hundred fourteen thousand twenty two = 814022
在样例4中,我们看到了量词的叠加,几百个的几千,假如用我们刚才的那套算法,memo在遇到hundred时就被置空了,便无法实现让thousand的量词memo = 800+14
为应对此问题,遍历过程中,我们可以搜索第i个元素后面有没有符合作为量词条件的字符串,如果有,我们应该用memo将其记录,如果没有,我们应该直接加入ans中。
模拟:对于样例4: eight hundred fourteen thousand twenty two
v[0]=eight 后面有量词hundred memo+=8
v[1]=hundred 后面有量词thousand memo*=100 (memo=800)
v[2]=fourteen 后面有量词thousand memo+=14 (memo=814)
v[3]=thousand 后面无量词 ans+=memo*1000 (ans=814000) memo=0
v[4]=thousand 后面无量词 ans+=20 (ans=814020) memo=0
v[5]=thousand 后面无量词 ans+=2 (ans=814022) memo=0
注:
据题意,我们知道输入符合数字的语法规范,即只能有A hundred B thousand,“几百个千”,
而不能有“几千个百”而引起歧义。
对于类似eight thousand six hundred的输入,应该在搜索thousand后的量词时,回避hundred。
AC代码如下:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
vector<string> v; //储存所有字符串的容器
int ans = 0; //答案
int sign = 0; //0默认为正 1为负
bool judge(int t)//判断t位置后是否有合法量词
{
int ret = 0;
if (v[t] == "million")return true; //不会有million million,并且million不可能作为hundred/thousand的数词
if (v[t] == "thousand")ret = 1;//过滤hundred,因为正确的说法是几百个千,而不是几千个百
for (int i = t + 1; i <= v.size() - 1; i++)
{
if (v[i] == "hundred")ret -= 1;
if (v[i] == "million" || v[i] == "thousand")
return false; //后续有量词
}
if (ret >= 0)
return true; //后续没有量词
else return false; //后续有量词
}
int main()
{
string s;
while(cin>>s)v.push_back(s);
int memo = 0; //用于储存上一个输入的数字,便于对其进行hundred、thousand等操作
for (int i = 0; i <= v.size() - 1; i++) //遍历获取的每个字符串
{
if (v[i] == "negative") {sign = 1; continue;}//负数
int temp = 0; //临时储存数据
/* 1---9 需要用memo记录,应对one hundred等情况 */
if (v[i] == "one") { temp = 1; }
if (v[i] == "two") { temp = 2; }
if (v[i] == "three") { temp = 3; }
if (v[i] == "four") { temp = 4; }
if (v[i] == "five") { temp = 5; }
if (v[i] == "six") { temp = 6; }
if (v[i] == "seven") { temp = 7; }
if (v[i] == "eight") { temp = 8; }
if (v[i] == "nine") { temp = 9; }
/* 10---90 */
if (v[i] == "ten") { temp = 10; }
if (v[i] == "eleven") { temp = 11; }
if (v[i] == "twelve") { temp = 12; }
if (v[i] == "thirteen") { temp = 13; }
if (v[i] == "fourteen") { temp = 14; }
if (v[i] == "fifteen") { temp = 15; }
if (v[i] == "sixteen") { temp = 16; }
if (v[i] == "seventeen") { temp = 17; }
if (v[i] == "eighteen") { temp = 18; }
if (v[i] == "nineteen") { temp = 19; }
if (v[i] == "twenty") { temp = 20; }
if (v[i] == "thirty") { temp = 30; }
if (v[i] == "forty") { temp = 40; }
if (v[i] == "fifty") { temp = 50; }
if (v[i] == "sixty") { temp = 60; }
if (v[i] == "seventy") { temp = 70; }
if (v[i] == "eighty") { temp = 80; }
if (v[i] == "ninety") { temp = 90; }
/* 量词 直接对之前记忆的数据进行操作即可 */
if (v[i] == "hundred") { memo *= 100; }
if (v[i] == "thousand") { memo *= 1000; }
if (v[i] == "million") { memo *= 1000000; }
//判断后续是否有合法量词 | 若有,则加入memo,否则加入ans
if (judge(i)) //没有合法量词,答案直接加上,再把memo置空
{
ans += memo + temp;
memo = 0;
}
else //有量词,不选择直接加ans里,而加入memo记忆储存
{
memo += temp;
}
}
if (sign == 1)cout << "-";
cout << ans << endl;
return 0;
}