poj.org/problem?id=3353

这道题,10%的AC率,看着有点害怕

Total Submissions: 593 Accepted: 54

但是题目读起来并不能难,只是简单得类似罗马数字跟阿拉伯数字的转换;不过仔细阅读却发现题意非常不清晰,没有任何提示说明答案是唯一的,但是题目有没有special judged,所以只能自行断定有歧义的情况应该坐如何选择

1. IVI是不合法的,虽然也可以解释成5,但是5只能是V, 也就是说任何数位都只能用唯一一种表示方法

2. MMMM是不合法的, MMM是合法的,>=4000的字段需要用O

比较有意思的是在我WA了3此后,只好去udebug上碰碰运气,结果还有一样名字的题目,于是乎我就随机生成了几组数据,看看AC的程序是啥样子的,通过对比:

1. 我的代码有个数据未重新初始化的bug,两个大数相加时需要补位的时候,需要两个数位的清零都考虑

2. udebug上的900是用DCD表示的, 而poj改成用CM表示

3. udebug上最多只允许1个O,但是poj允许多个O

所以原题不需要使用大整数,因为最多只有一个O, 那么最大也不过是100*1000*1000,但是poj的版本把题目难度增加了一丢丢,这里为poj点个赞~

实现:

解析字符串 -> 1000进制数组

char eval(char *p) {st=0;int v=0, m=100000000, c;int i=0; while(p[i]) { p[i]=mk[p[i]]; i++; }for (i=0; p[i]; ) {if (p[i]=='O') {if (st==0 && v<=3) return 0;sk[st++]=v;v=0; m=1000;i++;} else if (p[i]=='M') {if (m<=1000) return 0;while(p[i]=='M') { v+=1000; i++; }m=1000;} else if (p[i]=='D') {if (m<=100) return 0;v+=500;i++;// if (p[i]=='C'&&p[i+1]=='D') { i+=2; v+=400; }if (0) {}else {c=0;while(p[i]=='C') { i++; c++; v+=100; }if (c>3) return 0;}m=100;} else if (p[i]=='C') {if (m<=100) return 0;m=100;if (p[i+1]=='M') {// return 0;v+=900; i+=2;} else if (p[i+1]=='D') {v+=400; i+=2;} else {c=0; while(p[i]=='C') { i++; c++; v+=100; }if (c>3) return 0;}} else if (p[i]=='L') {if (m<=10) return 0;v+=50;c=0; i++; while(p[i]=='X') { i++; c++; v+=10; }if (c>3) return 0;m=10;} else if (p[i]=='X') {if (m<=10) return 0;m=10;if (p[i+1]=='C') {v+=90; i+=2;} else if (p[i+1]=='L') {v+=40; i+=2;} else {c=0; while(p[i]=='X') { i++; c++; v+=10; }if (c>3) return 0;}} else if (p[i]=='V') {if (m<=1) return 0; m=1;v+=5;c=0; i++; while(p[i]=='I') { i++; c++; v+=1; }if (c>3) return 0;m=1;} else if (p[i]=='I') {if (m<=1) return 0;m=1;if (p[i+1]=='X') {v+=9; i+=2;} else if (p[i+1]=='V') {v+=4; i+=2;} else {c=0; while(p[i]=='I') { i++; c++; v+=1; }if (c>3) return 0;}} else assert(0);if (v>=4000) return 0;}sk[st++]=v;// if (st>2) return 0;return 1;
}

将0-999之间的阿拉伯数字转换为罗马数字

int conv(char *p, int v) {int c=0;if (v>=900) {// p[c++]='D';// p[c++]='C';// p[c++]='D';p[c++]='C';p[c++]='M';v-=900;}if (v>=500) {p[c++]='D';v-=500;}if (v>=400) {p[c++]='C';p[c++]='D';v-=400;}while(v>=100) {p[c++]='C';v-=100;}if (v>=90) {p[c++]='X';p[c++]='C';v-=90;}if (v>=50) {p[c++]='L';v-=50;}if (v>=40) {p[c++]='X';p[c++]='L';v-=40;}while(v>=10) {p[c++]='X';v-=10;}if (v>=9) {p[c++]='I';p[c++]='X';v-=9;}if (v>=5) {p[c++]='V';v-=5;}if (v>=4) {p[c++]='I';p[c++]='V';v-=4;}while(v>=1) {p[c++]='I';v-=1;}return c;
}

主函数整体处理

  while(scanf("%s", &ib)==1) {i=0; while(ib[i]&&ib[i]!='+') i++;if (ib[i]==0) assert(0); ib[i]=0;if (eval(ib)==0) { printf("INVALID\n"); continue;}c1=0; while(st) { --st; v1[c1++]=sk[st]; }if (c1==1&&v1[0]==0) assert(0);if (eval(ib+i+1)==0) { printf("INVALID\n"); continue;}c2=0; while(st) { --st; v2[c2++]=sk[st]; }if (c2==1&&v2[0]==0) assert(0);mc=c1; if (mc<c2) mc=c2;for (i=c1; i<mc; i++) v1[i]=0;for (i=c2; i<mc; i++) v2[i]=0;v=0; for (i=0; i<mc; i++) { v=v1[i]+v2[i]+v; v1[i]=v%1000; v/=1000; }while(v) { v1[mc++]=v%1000; v/=1000; }k=0; for (i=mc-1; i>=0; i--) {v=v1[i]; if (i==mc-1&&i>0&&v<=3) {while(v) { ob[k++]='M'; v--; }} else {k+=conv(ob+k, v);if (i) ob[k++]='O';}}ob[k++]='=';for (i=mc-1; i>=0; i--) {v=v1[i]; st=0; for (j=0; j<3; j++) sk[j]=0;while(v) { sk[st++]=v%10; v/=10; } if (st==0) st=1;if (i==mc-1) {while(st) { st--; ob[k++]=sk[st]+'0'; }} else {for (j=2; j>=0; j--) ob[k++]=sk[j]+'0';}}ob[k++]=0;printf("%s\n", ob);}

题不难,就是题意模糊,但是终究可以通过试错来定位到题意,算是很恶心的地方

2730

POJ3353 1000进制大整数|水题|题意揣摩相关推荐

  1. 从10进制到1000进制:一场数字的盛宴

    本篇博客会讲解力扣"1920. 基于排列构建数组"的解题思路,这是题目链接. 先来审下题: 以下是输出示例: 以下是提示: 相信读完题的你已经感到没啥意思了,感觉做这道题就是在浪费 ...

  2. 74160ENT引脚设计法接成1000进制加法计数器

    之前和大家介绍了如何用74160ENT引脚设计法接成100进制加法计数电路, 下面我将解析该如何用74160ENT引脚设计法接成1000进制加法计数电路. 题目: 用3片74160.2片与门接成100 ...

  3. HDU2076 夹角有多大【水题】

    夹角有多大(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...

  4. python中不同进制的整数之间可以直接运算_Python 进制转换、位运算

    一.进制转换 编程用十进制,十进制转换为二进制.八进制.十六进制 In [135]: bin(23) Out[135]: '0b10111' In [136]: oct(23) Out[136]: ' ...

  5. python中不同进制的整数之间可以直接运算_python学习第三天总结(进制与位运算,)...

    进制 计算机在存储数字的时候都是以二进制的形式去存的 十进制.十六进制.八进制.二进制 1.十进制 基数:0,1,2,3,4,5,6,7,8,9 进位:逢10进1 每一位的值: 111 = 1 * 1 ...

  6. 高中信息技术——进制与编码刷题点整理

    前言:进制与编码是信息技术最基础最入门的知识点. 1. 进制转换   人类目前最常用的进制是十进制,很大可能也是跟人的手指有10根相关,人类可以简单的区分10中不同的数字.但是对于计算机来说,很多都是 ...

  7. 两片74161实现60进制_数字逻辑题:用74161构成7进制计数器分别采用复位法和置数...

    74161 是四位二进制同步计数器,有数据置入功能.未计数前,将输出QD,QC,QB,QA,置成10 3)按计数增减分:加法计数器,减法计数器,加减法计数器. 7.3.1 异步计数器 一,异步 可以3 ...

  8. python中不同进制的整数之间可以直接运算吗_【python公开课|要想真的做好python,那么学会python整数的不同进制很重要】- 环球网校...

    [摘要]在这个科学技术高速发展的时代,越来越多的人都开始选择学习编程软件,那么首先被大家选择的编程软件就是python,也用在各行各业之中,并被大家所熟知,所以也有越来越多的python学习者关注py ...

  9. 怎么做蒙特卡洛计算npv_计算机一级:这该死的“进制转换”,这种题到底怎么做?...

    不管是计算机一级,还是计算机二级, 选择题里都会涉及到" 进制转换 "的相关计算 分值大概在2-3分! 考试中题目大多数这样的: 我.............这真的太难了! 当然, ...

最新文章

  1. 斯隆-凯特琳癌症中心使用RTLS系统,改善患者术后护理流程
  2. application/x-www-form-urlencoded multipart/form-data text/plain 的区别和作用
  3. FAT32文件系统结构分析
  4. pip安装python模块遇到一直出现retrying的问题
  5. Java集合框架(一)
  6. tcl/tk demo
  7. [译文]通过一个通俗易懂的方式来了解下WebAssembly(一)
  8. Python 带你来一次说走就走的环球旅行
  9. GO语言的进阶之路-Golang高级数据结构定义
  10. [02.20][中国][人再囧途之泰囧][HD-RMVB.720p.国语中字][2012年喜剧]
  11. html2d动画,HTML5之SVG 2D入门11—用户交互性(动画)介绍及应用
  12. 十年之痛解读日本房地产泡沫
  13. Configuring solrconfig.xml (1)
  14. 没比这更简单的了!安装PHP composer(windows环境)及简易使用
  15. nginx之allow、deny
  16. 图书管理系统之带验证码登录界面
  17. element-ui快速使用(使用element-ui做一个表格)
  18. Zookeeper连接异常 Got ping response for sessionid 2021-06-30
  19. IPv6技术精要--第17章双栈和隧道
  20. oracle 建分区索引_Oracle的分区表和Local索引创建与维护

热门文章

  1. 初学FS4412——简介和点灯
  2. 原创:sqlite数据库转换为mysql数据库
  3. myo学习(1):安装入门
  4. 树形结构递归查询,删除等封装处理
  5. 2022 清华大学 自动化系 保研推免 面试经验
  6. opencv-膨胀 dilate()
  7. 超神学院中基因计算机原理,超神学院里的神级选择系统
  8. 无源光网络(PON) VS有源光网络(AON)
  9. 关于Futaba T 14SG遥控器的配置
  10. 前端代码规范 及 最佳实践