**Description
在那个风起云涌的SCAU ACM里,有两位人生赢家,他们分别是大洲Takio神和Blue神。 (尤其是blue神。)
由于这两位人生赢家代码能力强,才高八斗,学富五车,英俊潇洒,玉树临风,独步江湖,呼风唤雨,妹子纷至沓来。
而小邪由于太渣了,只能默默地帮他们记录下他们换了多少个妹子。
以上背景纯属题目需要,其实两位大神是很专情的。
终于有一天,小邪计算出他们身边妹子的总数n,想要给Takio神和Blue神。
但是Takio神和Blue神的邮箱是使用英文的,而小邪的英语又很渣,于是无法将n翻译成英语发过去。
但是,小邪想到了你——聪明的14级新生,向你寻求答案。
出题人:K·小邪
输入格式
第一行是一个整数t(t <= 100),代表样例个数
对于每个样例有一个整数n(0<=n<=2000000000)
输出格式
对于每个n,输出其英文表现形式,具体格式见样例输出
输入样例
4
5
121
1010
1008611
输出样例
five
one hundred and twenty-one
one thousand and ten
one million, eight thousand, six hundred and eleven
提示
输出不一定符合英语规范,但是要符合Sample的规范
对于一个n>1000,若n%1000 >= 100(%代表取余操作)且不为0,且在n%1000对应的英文输出前(如果存在)用”,”相连而不是”and”
需要用到的英文单词为(不包括引号):
“zero”,”one”,”two”,”three”,”four”,”five”,”six”,”seven”,”eight”,”nine”
“ten”,”eleven”,”twelve”,”thirteen”,”fourteen”,”fifteen”,”sixteen”,”seventeen”,”eighteen”,”nineteen”
“twenty”,”thirty”,”forty”,”fifty”,”sixty”,”seventy”,”eighty”,”ninety”
“hundred”,”thousand”,”million”,”billion”
分别代表
0,1,2,3,4,5,6,7,8,9
10,11,12,13,14,15,16,17,18,19
20,30,40,50,60,70,80,90
100,1000,1000000,1000000000
**
我的第一篇blog,那我就先写一份纯自己想自己码的题解和代码吧。
题意:输入若干个不大于2e9的正整数,要求把每个整数用其对应的英文表示输出。
分析:没错,纯模拟,做模拟题可以说是提高码力最暴力也是最好的方法了吧。可以观察到,英文的表达跟他们的一些计数形式是有一定关联的,比如1,000,000,000,就是每三个位分为一部分,我们可以从这里入手,分步解决,把代码模块化(似乎养成这个好习惯很重要),确保代码的简洁,调试debug也更容易,上代码(:з)∠)。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <cctype>
#include <stack>
#define mst(a,b) memset(a,b,sizeof(a));
const int mod = (int)1e9+7;
const int maxn = 1e5+5;
typedef long long LL;
using namespace std;
//bool judge[maxn];
char word[5][5];
char first[11][20] = {"zero","one","two","three","four","five","six","seven","eight","nine"};
char second[11][20] = {"ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
char third[11][20] = {"","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
char forth[11][20] = {"hundred","thousand","million","billion"};
int gcd(int a, int b)
{
return (b==0)?a:gcd(b, a%b);
}
int temp;
void gg(int n)
{
if(word[n][1]-'0' == 1){
printf("%s", second[word[n][0]-'0']); //每一部分“十”位是否为1。
}
else{ //处理方式类似gg1
if(word[n][1] == 0||word[n][1] == '0') printf("%s", first[word[n][0]-'0']);
else if(word[n][0]!='0'&&word[n][1]!='0')printf("%s-%s", third[word[n][1]-'0'], first[word[n][0]-'0']);
else if(word[n][0]=='0') printf("%s",third[word[n][1]-'0']);
}
}
void gg1(int n)
{
if(n!=temp) { //最高位那一部分,因为“and ”“, ”是接在每一部分的前面的,而最高位不用接。
if(n==0&&word[n][2]-'0' == 0) printf(" and ");
else printf(", ");
}
if(word[n][2]!='0'&&word[n][2]){ //每一部分的“百”位是否为0。应为最高位的百位我们是没有‘0’的,所以应该判断是否为0。
if(word[n][0]!='0'||word[n][1]!='0') {printf("%s hundred and ", first[word[n][2]-'0']);gg(n);}
else printf("%s hundred",first[word[n][2]-'0']); //“个十”位都为0。
}
else gg(n);
}
void solve(int n)
{
if(word[n][0]!='0'||word[n][1]!='0'||word[n][2]!='0'){ //若这一部分3个位都为0就什么也不干。
if(n == 0) gg1(n); //最后一部分,即个十百位。
else{
gg1(n);
printf(" %s",forth[n]); //非最后一部分要加个后缀。
}
}
}
int main()
{
int t, len, temp1;
char s[11];
scanf("%d", &t);
while(t--){
temp = temp1 = 0;
mst(word, 0);
scanf("%s", s);
len = strlen(s);
for(int i = 0; i < len; i++){
if(i%3==0&&i!=0) {temp++;temp1 = 0;}
word[temp][temp1++] = s[len - i - 1]; //分块每3位存起来。
}
for(int i = temp; i >= 0; i--){
solve(i); //由高位到低位逐个解决。
}
printf("\n");
}
return 0;
}
总结一下,注意代码模块化之后会发现debug非常简单一旦你发现了bug,做模拟题要注意不要把处理部分全部挤在主函数里面,而且会有一些重复的处理方法,挤在一起会显得代码很长,从而削减你debug的信心(有bug的情况下),况且模拟题是最容易出现bug的;所以,模块化以后代码会变得美观,重复部分只需要一个函数就行了,多简单。