您的位置:首页 > 编程语言 > C语言/C++

USACO 2.2 Preface Numbering

2015-03-17 14:49 417 查看
        这道题让我想到了之前Chapter 1的计算星期五的那道题。

        罗马数字的书写规律见罗马数字。在我的理解中,罗马数字就是十进制的复杂版,每一个位数上的数字单独转化成一组字母,这样罗马数字的书写就完成了。也就是说,只要计算出每个位数的数字会对应哪几个字母,就可以方便地计算了。比如说,在十位数上的9,其书写一定是XC。

        由此,我做了两件事情:

        (1) 记录每个位数上1-9的字母组合

        (2) 遍历范围内的数字,分离它的每一位,并依次加入总数的计算

        附上代码:

#include <iostream>
#include <fstream>
using namespace std;

int nums[7];
int dict[4][10][9];
int N;

void initData()
{
ifstream fin ("preface.in");
int i;

fin >> N;

for (i = 0; i < 4; i ++) {
dict[i][1][i*2] = 1;
dict[i][2][i*2] = 2;
dict[i][3][i*2] = 3;
dict[i][4][i*2] = 1;
dict[i][4][i*2+1] = 1;
dict[i][5][i*2+1] = 1;
dict[i][6][i*2] = 1;
dict[i][6][i*2+1] = 1;
dict[i][7][i*2] = 2;
dict[i][7][i*2+1] = 1;
dict[i][8][i*2] = 3;
dict[i][8][i*2+1] = 1;
dict[i][9][i*2] = 1;
dict[i][9][i*2+2] = 1;
}
}

int main()
{
initData();
ofstream fout ("preface.out");
int i, j;
int m, n;

for (i = 1; i <= N; i ++) {
for (n = 0, m = i; m / 10 != 0; n ++, m /= 10)
for (j = 0; j < 8; j ++)
nums[j] += dict
[m%10][j];
for (j = 0; j < 8; j ++)
nums[j] += dict
[m][j];
}

if (nums[0] != 0)
fout << "I " << nums[0] << endl;
if (nums[1] != 0)
fout << "V " << nums[1] << endl;
if (nums[2] != 0)
fout << "X " << nums[2] << endl;
if (nums[3] != 0)
fout << "L " << nums[3] << endl;
if (nums[4] != 0)
fout << "C " << nums[4] << endl;
if (nums[5] != 0)
fout << "D " << nums[5] << endl;
if (nums[6] != 0)
fout << "M " << nums[6] << endl;
}

        其中的dict数组的维数含义是这样的:第一个代表的是位数,第二个是数字本身,第三个代表IV...M的全组。
        举个例子来说,比如我遍历到了572这个数字,那么对于其中的5,我应当查看dict[2][5][0...7]这一排;对于其中的7,我应当查看dict[1][7][0...7]这一排;对于其中的2,我应当查看dict[0][2][0...7]这一排。

        闲话时间。这道题的用时基本都花在理解题意上了,一旦明白了它的运作方式,逻辑上是没有坑的。我不太喜欢做这种可以hardcode的题目……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息