ZOJ 2071 Give Me the Number

Numbers in English are written down in the following way (only numbers less than 109 are considered). Number abc,def,ghi is written as "[abc] million [def] thousand [ghi]". Here "[xyz] " means the written down number xyz .

In the written down number the part "[abc] million" is omitted if abc = 0 , "[def] thousand" is omitted if def = 0 , and "[ghi] " is omitted if ghi = 0 . If the whole number is equal to 0 it is written down as "zero". Note that words "million" and "thousand" are singular even if the number of millions or thousands respectively is greater than one.

Numbers under one thousand are written down in the following way. The number xyz is written as "[x] hundred and [yz] &#148. ( If yz = 0 it should be only &#147[x] hundred&#148. Otherwise if y = 0 it should be only &#147[x] hundred and [z]&#148.) Here "[x] hundred and" is omitted if x = 0 . Note that "hundred" is also always singular.

Numbers under 20 are written down as "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", and "nineteen" respectively. Numbers from 20 to 99 are written down in the following way. Number xy is written as "[x0] [y] ", and numbers divisible by ten are written as "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", and "ninety" respectively.

For example, number 987,654,312 is written down as "nine hundred and eighty seven million six hundred and fifty four thousand three hundred and twelve", number 100,000,037 as "one hundred million thirty seven", number 1,000 as "one thousand". Note that "one" is never omitted for millions, thousands and hundreds.

Give you the written down words of a number, please give out the original number.

Input

Standard input will contain multiple test cases. The first line of the input is a single integer T (1 <= T <= 1900) which is the number of test cases. It will be followed by T consecutive test cases.

Each test case contains only one line consisting of a sequence of English words representing a number.

Output

For each line of the English words output the corresponding integer in a single line. You can assume that the integer is smaller than 109.

Sample Input

3
one
eleven
one hundred and two

Sample Output

1
11
102

思路分析 : 

本题考查将字符串转化为数字的能力。首先  ,, 就表示遇到“million","thousand","hundred"需要分开表示,最后求三者和。由于million与hundred前面都可能存在三位数,即百位。因此hundred需要与million和thousand进行区分,且hundred需要防于million和thousand之前。

因此,本题的字符串转化顺序为:先判断是否为单独一个数,可以进行直接表示的数。如最简单的20以内的数,直接可以用对应数组下标来表示,但是此题为字符串转化题,显然不太合适,如果转成一维数组,处理thousand和million时较为不便。

因此,可以采取用map<string,int>n, 定义一个[ ]内键为字符,值为整数,为其代表的数。对于0到20,我们采用一重循环,由于i与键一一对应,因此直接把a[i]作为键,值为i。

对于大于等于20且小于等于90的整十的数字,采取用a[j]来作 键,值为i。i在一重循环内需要注意是10个10个加且初值为20。

对于hundred,thousand,million,采取形如dan["hundred"]=100方式处理。

输入一个字符串后,用getchar()储存空行或空格。可以用来最后判定是否结束。

从头开始遍历,看输入字符串是否属于比较简单可以直接在num找到,可以就在后续直接输出。不能,先加上求和,接着遍历遇到hundred时,相应乘100;遇到million或thousand,相应乘,但是由于这两个的间隔作用,因此求和需要置0.

最后把三组分别的结果相加即为结果。

 注意 :

1.num.count(n)是判断n是否存在。

2. 由于million前后,thousand前后均有可能出现三位即hundred情况,因此需要把hundred放在million和thousand之前判断。

代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,int> num,dan;
void Kira() {
	string a[]= {"zero", "one", "two", "three", "four", "five", "six",
	             "seven", "eight", "nine", "ten", "eleven", "twelve",
	             "thirteen", "fourteen", "fifteen", "sixteen",
	             "seventeen", "eighteen", "nineteen"
	            } ;
	string b[]= {"twenty", "thirty", "forty", "fifty",
	             "sixty", "seventy", "eighty", "ninety"
	            };
    for(int i=0;i<20;i++){
	    num[a[i]]=i;
    }
    for(int i=20,j=0;i<=90;j++,i+=10){
    	num[b[j]]=i;
	}
	dan["hundred"]=100;
	dan["thousand"]=1000;
	dan["million"]=1000000;
}

int main() {
    int T;
    cin>>T;
    Kira(); 
    while(T--){
    	string str;
    	int arr[2]={0};
    	int ans=0;
    	while(cin>>str){
    		char ch=getchar();//储存换行符 
    		if(num.count(str)==1)/*num.count(n)在num中查找n
			 有,存在为1.没有,不存在,为0*/ 
			    ans+=num[str];
    		else if(str=="hundred"){
    			ans*=dan[str];
			}
			if(str=="million"){
				arr[0]=ans*dan[str];
				ans=0;
			}
			else if(str=="thousand"){
				arr[1]=ans*dan[str];
				ans=0;
			}
			if(ch=='\n')break;
	}
	cout<<arr[0]+arr[1]+ans<<endl;
	}
}

 运行结果  :

个人小结 : 

这是在校acm第二次集训,这一题咋一样觉得简单,实则不然,我认为根源在于说我的思维模式被之前的英文A+B固定住了,思维不灵通。

一味想用简单数组来做,可惜这是竞赛,不是课后作业。

还需要补一些字符串的相关知识。比如这一题,就是根据c站的转载的大佬学了一二,还不算懂,有空多加复习吧。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值