USACO:2.2.1 Preface Numbering 序言页码

一、题目描述

★Preface Numbering 序言页码

一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,一下是标准数字
表:
I 1 L 50 M 1000
V 5 C 100
X 10 D 500
最多3 个可以表示为10n 的数字(I,X,C,M)可以连续放在一起,表示它们的和:
III=3
CCC=300
可表示为5x10n 的字符(V,L,D)从不连续出现.
除了下一个规则,一般来说,字符以递减的顺序接连出现:
CCLXVIII = 100+100+50+10+5+1+1+1 = 268
有时,一个可表示为10^n 的数出现在一个比它大的数前(I 在V 或X 前面,X 在L 或C 前面,等等).
在这种情况下,数值等于后面的那个数减去前面的那个数:
IV = 4
IX = 9
XL = 40
像XD, IC, 和XM 这样的表达是非法的,因为前面的数比后面的数小太多.对于XD(490 的错误表达),
可以写成 CDXC; 对于IC(99 的错误表达),可以写成XCIX; 对于XM(990 的错误表达),可以写成
CMXC.
给定N(1 <= N < 3,500), 序言的页码数,请统计在第1 页到第N 也中,有几个I 出现,几个V 出现,
等等 (从小到大的顺序).不要输出并没有出现过的字符.
比如N = 5, 那么页码数为: I, II, III, IV, V. 总共有7 个I 出现,2 个V 出现.
PROGRAM NAME: preface
INPUT FORMAT

一个整数N.
SAMPLE INPUT(preface.in)
5
OUTPUT FORMAT
每行一个字符和一个数字k,表示这个字符出现了k 次.字符必须按数字表中的递增顺序输出.
SAMPLE OUTPUT(preface.out)
I 7
V 2

二、解题思路

首先我们都能想到的就是枚举,枚举一般来说比较简单,思路清晰。没有什么复杂的算法和数据结构。

我们仔细分析题目,发现如下规律:(分析找规律的建模过程很重要!)

标准数字表:

I   1     L   50   M  1000
V   5     C  100
X  10     D  500 

可建一个表存储,ch[8]={'I','V','X','L','C','D','M'}

分析得出,对应个、十、百和千位的数字表
('','I','II','III','IV','V','VI','VII','VIII','IX'),//个位,0,1,2,...,9
('','X','XX','XXX','XL','L','LX','LXX','LXXX','XC'),//十
('','C','CC','CCC','CD','D','DC','DCC','DCCC','CM'),//百
('','M','MM','MMM','','','','','',''));//千

通过查看上表,排列相当有规律。从个位到千位,不仅形式没变,而且字符变化是标准数字表中字符位置的相同偏移递增。因此,我们可以利用这个特征来简化枚举的操作,对每个数字从个位到千位,通过字符偏移量进行查表,逐位进行字符计数。

我的程序实现如下:

#include <iostream>
#include <cstdio>using namespace  std;int N;
int vis[7];
char c[8]={'I','V','X','L','C','D','M'};
// I   1     L   50   M  1000
// V   5     C  100
// X  10     D  500
// ('','I','II','III','IV','V','VI','VII','VIII','IX'),//个
// ('','X','XX','XXX','XL','L','LX','LXX','LXXX','XC'),//十
// ('','C','CC','CCC','CD','D','DC','DCC','DCCC','CM'),//百
// ('','M','MM','MMM','','','','','',''));//千
void cnt(int x,int digit){//个位//if(digit==1){int var;var=2*(digit-1);//对应个、十、百和千数位的数字表相对位移if (1<=x&&x<=3){vis[0+var]=vis[0+var]+x;}else if(x==4){vis[0+var]=vis[0+var]+1;vis[1+var]=vis[1+var]+1;}else if(x==5){vis[1+var]=vis[1+var]+1;}else if (6<=x&&x<=8){vis[0+var]=vis[0+var]+x-5;vis[1+var]=vis[1+var]+1;}else if (x==9){vis[0+var]=vis[0+var]+1;vis[2+var]=vis[2+var]+1;       }
}void dfs(int N,int digit){int num=N%10;if (num!=0){ //&& (num%10)!=0cnt (num,digit);}if(N/10!=0){N=N/10;dfs(N,digit+1);     }
}int main(){freopen("preface.in","r",stdin);freopen("preface.out","w",stdout)p;int i;cin>>N;for(i=0;i<=N;i++)dfs(i,1);for (i=0;i<7;i++){ if (vis[i]!=0)cout<<c[i]<<" "<<vis[i]<<endl;}return 0;
}//USACO参考答案
// We use a lookup table called "encode" to encode each digit, translating from the letters
// for the ones place to the letters for the place that we care about.
// The "romandigit" function takes care of each digit, and the "roman" function strings them all together./*
PROG: preface
ID: rsc001
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>static char *encode[] = {   //编码,指针字符数组,已初始化"", "I", "II", "III", "IV","V", "VI", "VII", "VIII", "IX",
};char*
romandigit(int d, char *ivx) //返还字符指针,指向一个字符
{char *s, *p;static char str[10];for(s=encode[d%10], p=str; *s; s++, p++) {switch(*s){case 'I':*p = ivx[0];break;case 'V':*p = ivx[1];break;case 'X':*p = ivx[2];break;}}*p = '\0';return str;
}char*
roman(int n)
{static char buf[20];strcpy(buf, "");strcat(buf, romandigit(n/1000, "M"));//拼接1000strcat(buf, romandigit(n/100,  "CDM"));strcat(buf, romandigit(n/10,   "XLC"));strcat(buf, romandigit(n,      "IVX"));return buf;
}void
main(void)
{FILE *fin, *fout;int i, n;char *s;int count[256];fin = fopen("preface.in", "r");fout = fopen("preface.out", "w");assert(fin != NULL && fout != NULL);fscanf(fin, "%d", &n);for(s="IVXLCDM"; *s; s++)//字符指针,指向字符串首地址,比较巧妙count[*s] = 0; //将字符的ascii值为索引的位置初始化为0 for(i=1; i<=n; i++)for(s=roman(i); *s; s++)count[*s]++;for(s="IVXLCDM"; *s; s++)if(count[*s])fprintf(fout, "%c %d\n", *s, count[*s]);exit(0);
}

由于自身是初学者,编程能力有限,未达到专业程序员的水平,可能误导大家,请大家甄读;文字编辑也一般,文中可能会有措辞不当。博文中的错误和不足敬请读者批评指正。

USACO:2.2.1 Preface Numbering 序言页码相关推荐

  1. usaco Preface Numbering 序言页码

    Preface Numbering 序言页码 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,一下是标准数字 表: I 1 L 50 M 1000 V 5 C 100 X 10 ...

  2. Preface Numbering序言页码

    题面 (preface.pas/c/cpp) 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,以下是标准数字表: I 1 V 5 X 10 L 50 C 100 D 500 M ...

  3. [USACO 2.2.1] Preface Numbering

    [题目描述] Preface Numbering 序言页码 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,一下是标准数字表: I 1 L 50 M 1000 V 5 C 10 ...

  4. preface numbering

    1262. [USACO题库]2.2.1 Preface Numbering序言页码 (Standard IO) 时间限制:  1000 ms  空间限制:  262144 KB  具体限制   题目 ...

  5. 序言页码(纯思维题)

    题目描述 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,一下是标准数字表: I 1 L 50 M 1000 V 5 C 100 X 10 D 500 最多3个可以表示为10n ...

  6. P1465 序言页码 Preface Numbering (手推)

    题目描述 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,以下是标准数字表: I 1 V 5 X 10 L 50 C 100 D 500 M 1000 最多3个同样的可以表示为 ...

  7. 洛谷P1465 [USACO2.2]序言页码 Preface Numbering

    题目描述 给定 nn,求 1 \sim n1∼n 的 罗马数字 表示中,各个字符出现了多少次. 比如 n = 5n=5,表示为 I, II, III, IV, V.总共有 77 个 I 出现,22 个 ...

  8. USACO Section2.2 Preface Numbering 解题报告 【icedream61】

    preface解题报告 ---------------------------------------------------------------------------------------- ...

  9. USACO-Section2.2 Preface Numbering

    2017-8-30 题目描述 序言的页码数,请统计在第1页到第N页中,有几个I出现,几个V出现... 解答 将已知存起来,不再重复计算,没有求的用已经求好的加起来 代码 /* ID: 18795871 ...

最新文章

  1. 马云出 1000 亿做阿里达摩院:产品卖到全球了,他说科学研究也要跟上
  2. javascript 之 push方法
  3. 把控制台程序嵌入到 WinForm 中执行
  4. FSAF 让网络自己决定实例输出层
  5. 《徐徐道来话Java》:PriorityQueue和最小堆
  6. 易被销售员忽略的销售细节
  7. java base64编码的三种方式
  8. 2-3实战分类模型之数据的读取与展示
  9. Linux 文件系统相关的命令
  10. mysql update 几万 非常慢_面试官:谈谈你对mysql索引的认识?
  11. Silverlight 国外技术文章
  12. 【模板】线性筛法求素数
  13. python如何截长图_python 截长图、H5页面截长图
  14. 如何提高你的个人价值
  15. Freeswitch 结合AIO100语音网关 发送短信
  16. 2022年房地产市场趋势展望
  17. java和python哪个运行速度快_python和java学哪个比较简单点
  18. PA认证考试说明及注意事项
  19. Ubuntu16.04笔记本 安装R RStudio
  20. 评弹,有些味道,可惜听不懂!

热门文章

  1. [经验教程]拼多多退店保证金多久到账 拼多多退店正确操作35天内保证金到账
  2. AASM rule of scoring sleep stages using EEG signal
  3. 开源生物特征识别库 OpenBR
  4. github登录+注册方法
  5. 音频信号处理——基音周期
  6. docker入门课程
  7. 我与AWS Proserve团队的故事
  8. 15.IGame游戏公司的故事
  9. [IOS APP]西藏生死书
  10. 台式计算机屏幕亮度在哪调,电脑亮度怎么调?教您电脑亮度在哪里调