北理乐学回文数的思考(附代码)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87,STEP1:87+78 = 165 STEP2:165+561 = 726 STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个N(2<=N<=10或N=16)进制数M(100位之内),求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”。进制N>10时,使用大写'A'字母表示10,'B'表示11,...,'E'表示15。
输入描述:两行,分别为N,M
输出描述:STEP=ans
输入例子:
9
87
输出例子:
STEP=6
提示:以下是本篇文章正文内容,下面案例可供参考(第一次写哈,纯纯新手,有错误随时指出,谢谢大家啦!)
目录
题目
思路分析
那么A这种怎么办?
总结
思路分析
面对这样的一道题,乍一看确实有点眼晕。但是,只要我们理清思路,就能够化繁为简,轻松写出属于自己的答案。
注意看,这道题有十六进制的限制,也就是说会有ABCDEF的字母来捣乱,我们不能像以往那样随便scanf个%d了。这里我有两种解决方案:
第一种就是通过字符数组的方式来读入,然后在进制转换的时候根据ASCII码表来进行代换。
ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
0 |
NUL |
32 |
(space) |
64 |
@ |
96 |
、 |
1 |
SOH |
33 |
! |
65 |
A |
97 |
a |
2 |
STX |
34 |
” |
66 |
B |
98 |
b |
3 |
ETX |
35 |
# |
67 |
C |
99 |
c |
4 |
EOT |
36 |
$ |
68 |
D |
100 |
d |
5 |
ENQ |
37 |
% |
69 |
E |
101 |
e |
6 |
ACK |
38 |
& |
70 |
F |
102 |
f |
7 |
BEL |
39 |
' |
71 |
G |
103 |
g |
8 |
BS |
40 |
( |
72 |
H |
104 |
h |
9 |
HT |
41 |
) |
73 |
I |
105 |
i |
10 |
LF |
42 |
* |
74 |
J |
106 |
j |
11 |
VT |
43 |
+ |
75 |
K |
107 |
k |
12 |
FF |
44 |
, |
76 |
L |
108 |
l |
13 |
CR |
45 |
- |
77 |
M |
109 |
m |
14 |
SO |
46 |
. |
78 |
N |
110 |
n |
15 |
SI |
47 |
/ |
79 |
O |
111 |
o |
16 |
DLE |
48 |
0 |
80 |
P |
112 |
p |
17 |
DCI |
49 |
1 |
81 |
Q |
113 |
q |
18 |
DC2 |
50 |
2 |
82 |
R |
114 |
r |
19 |
DC3 |
51 |
3 |
83 |
X |
115 |
s |
20 |
DC4 |
52 |
4 |
84 |
T |
116 |
t |
21 |
NAK |
53 |
5 |
85 |
U |
117 |
u |
22 |
SYN |
54 |
6 |
86 |
V |
118 |
v |
23 |
TB |
55 |
7 |
87 |
W |
119 |
w |
24 |
CAN |
56 |
8 |
88 |
X |
120 |
x |
25 |
EM |
57 |
9 |
89 |
Y |
121 |
y |
26 |
SUB |
58 |
: |
90 |
Z |
122 |
z |
27 |
ESC |
59 |
; |
91 |
[ |
123 |
{ |
28 |
FS |
60 |
< |
92 |
\ |
124 |
| |
29 |
GS |
61 |
= |
93 |
] |
125 |
} |
30 |
RS |
62 |
> |
94 |
^ |
126 |
~ |
31 |
US |
63 |
? |
95 |
— |
127 |
DEL |
我们知道: 58的时候不是什么所谓的字符'10',因为是按位存储。所以这里我们需要做个小转换。这里有个小技巧可以帮助我们快速从字符0123……9转换为数字的形式。举个例子:'4'变成4,我们可以通过间距法来快速得出:
4=‘4’-‘0’;
那么A这种怎么办?
同理哦 10=‘A’-‘0’-7;
我们看到A和9中间有7个位置,所以我们就需要减去这个7。这样我们就可以完成第一个小目标。
然后就按正常思路分析即可。这里留给大家思考,写出来的可以放在评论区一起讨论呀。
第二种解决方案是经由启发得出的,既然他十六进制限制我们,那我们直接%x读它不就完了?那有的同学问了:这也不都是十六进制呀?你这怎么弄?
别急,还没完呢。你看我慢慢道来:读完十六进制之后,我们根据题意肯定得做加法操作吧,那我们不能直接十六进制加吧,所以这里先换成十进制。代码如下:(这个转换进制相信学到现在大家能够完全掌握啦)
int N,M,a[10],b[10],step;scanf("%d %x",&N,&M);
for(int i=0;i<10;i++){a[i]=M%16;b[i]=0;M/=16;}
这里采用数组的形式,因为加法不就是一位一位加的嘛,所以数组处理起来比较方便。那么a【i】和b【i】就是两个翻转的数,根据题意设置的哈。这个10我们后期可以再调,反正我乐学过了,嘻嘻。接下来我们就需要构建几个函数。明白这个过程。
第一步,我们已经初始化了b【i】,这b里面现在都是0;现在a【i】是倒过来的,根据刚才那个程序我们就可以了解到。
这里首先设置第一个函数,我取名为reverse。他的主要目标就是把a的里面的数字反着输入进b中。但是我们不知道输入的位数是多少,所以我们首先得知道a到哪里碰见了那个‘\0’这里使用标志变量的方法:先设置flag=1,确保可以循环,从a【9】开始向前读,读到‘\0’让flag=0,这样结束循环,同时设置一个变量记录这个位数,我命名为cnt。
void reverse(int b[],int a[]){int cnt,flag=1;for(int i=9;i>=0&&flag;i--){if(a[i]){cnt=i;flag=0;}}for(int i=0;i<10;i++) b[i]=0;for(int i=0;i<=cnt;i++){b[i]=a[cnt-i];}}
接下来就是反着赋值啦。很简单的
第二步,构建第二个函数,我取名为intcmp。这个是用来比较每一位的差异,如果不同就返回1;如果相同就返回0。注意:这里面依然使用了标志变量flag来帮助我们决定循环的实时状态。
int intcmp(int a[],int b[]){int flag=0;for(int i=0;i<10;i++){if(a[i]!=b[i]) flag=1;}return flag;}
这个函数来帮助我们决定是否继续进行加法运算。
所以第三步,我们来写加法的函数构造,我取名为add。(比较好记)
思路分析:N是那个进制,因为我们现在十六进制已经转成十进制了,但是加法还得按着进制来。
不过我们只需要明确一点:N进制就是满N进一呗,和我们所熟悉的十进制是一样的哦。所以我们先进行位数的相加。
这里有两种情况:第一种就是加完以后小于N,那么我们就不需要另行操作,直接赋给a就好。第二种就是大于N,类比十进制,我们只需要将所得数先减去N,并且在下一位上加一就可以完美实现了。以下是代码:
void add(int N,int a[],int b[]){for(int i=0;i<10;i++){a[i]+=b[i];if(a[i]>=N){a[i]-=N;a[i+1]++;}}}
注:这里我将所得结果直接加到了a数组身上,这样b数组就没有发生改变。因为后续的b是a的反转,和他的自身初值没什么关系,所以就直接将所得的和赋到a身上了,在下一次的时候我们用reverse函数就行啦。
第四步,在我们构建好预备函数后,就可以来写main函数计算步数step了。(欢呼!)
int main(){int N,M,a[10],b[10],step;scanf("%d %x",&N,&M);for(int i=0;i<10;i++){a[i]=M%16;b[i]=0;M/=16;}for(step=0;step<=31;step++){reverse(b,a);if(intcmp(a,b)){add(N,a,b);}else break;}if(step<=30) printf("STEP=%d\n",step);else printf("Impossible!\n");return 0;}
这就是全貌了。分析一下:
我们通过for循环来计step的步数,一旦满足回文数条件,我们就直接跳出。如果小于等于30,输出step:如果大于,输出Impossible!循环内部:首先把a反转给b,这样有两个数组了。然后if判断这两个数组每一位是否完全一样,如果一样就满足回文数条件啦,intcmp会返回零,直接break出去。如果不一样,我们进入if内部,使用加法函数将两者相加并将新的数赋给a,step++一下,直到完全相同跳出for循环。此时step的值就可以用来判断了。
整体代码:
#include <stdio.h>void reverse(int b[],int a[]){int cnt,flag=1;for(int i=9;i>=0&&flag;i--){if(a[i]){cnt=i;flag=0;}}for(int i=0;i<10;i++) b[i]=0;for(int i=0;i<=cnt;i++){b[i]=a[cnt-i];}}void add(int N,int a[],int b[]){for(int i=0;i<10;i++){a[i]+=b[i];if(a[i]>=N){a[i]-=N;a[i+1]++;}}}int intcmp(int a[],int b[]){int flag=0;for(int i=0;i<10;i++){if(a[i]!=b[i]) flag=1;}return flag;}int main(){int N,M,a[10],b[10],step;scanf("%d %x",&N,&M);for(int i=0;i<10;i++){a[i]=M%16;b[i]=0;M/=16;}for(step=0;step<=31;step++){reverse(b,a);if(intcmp(a,b)){add(N,a,b);}else break;}if(step<=30) printf("STEP=%d\n",step);else printf("Impossible!\n");return 0;}
总结
以上就是今天要讲的内容,本文主要通过构造三个简单的函数,加法,判断回文数小条件,颠倒赋值,并且巧妙处理了N进制数,得到了整个问题的解。经过分析,这道题综合性很强,每一小步都需要一些思考和总结,在做完题目的时候真的需要及时复盘,这样才能更好的进步。就写到这里了,祝学习进步!
北理乐学回文数的思考(附代码)相关推荐
- C语言判断一个数是否是回文数Palindrome算法(附完整源码)
判断回文数Palindrome的算法 判断回文数Palindrome的算法完整源码(定义,实现,main函数测试) 判断回文数Palindrome的算法完整源码(定义,实现,main函数测试) #in ...
- python判断是否回文_对python判断是否回文数的实例详解
设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称n为一回文数:但若n=1234567,则n不是回文数. 上面的解释就是说回文数和逆 ...
- python怎么设置回文数_python如何写一个函数判断回文数?
python如何写一个函数判断回文数? python写一个函数判断回文数的方法: 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称 ...
- 20200119:(leetcode)回文数(3种解法)
回文数 题目 基本思路 代码实现 题目 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -1 ...
- 判断一个整数是否是回文数
2019独角兽企业重金招聘Python工程师标准>>> 这段代码是我做leetcode练习题时写的,虽然实现了回文数的识别,但是倒置后的数字不是一个完整的数字,而是由几个输出拼接而成 ...
- java如何判断回文数
java如何判断回文数 什么是回文数?数值两边呈对称的数是回文数,比如121,12321,1234321- 但是回文数应该怎么判断呢,以121举例子: 121%(取余)10得到了1, 12%10得到了 ...
- 判断一个整数是否为回文数
一.题目描述 二.思路 (1)可以将该整数转换成字符串,根据字符串的长度奇偶性来确定中间位置,然后首尾进行对比是否是回文数字.此时需要额外空间来存储字符串,然后进行判断 (2)可以将整数的最后一半数字 ...
- python回文数判定_python如何写一个函数判断回文数?
python如何写一个函数判断回文数? python写一个函数判断回文数的方法: 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称 ...
- 判断回文数的两种解法
一.首先什么是回文数呢? "回文"是指正读反读都能读通的句子,它是古今中外都有的一种修辞方式和文字游戏,如"我为人人,人人为我"等.在数学中也有这样一类数字有这 ...
最新文章
- 查找谁在使用文件系统
- mysql负载均衡与同步_MySql数据库从同步负载均衡实时备份
- 能力素质有所欠缺_孩子说话啰嗦没重点?家长学会“大脑整理术”,提高孩子表达能力...
- Qt中的TCP客户端编程
- Mybatis:基于注解形式,传入List,返回List实体
- java arraybound out_java – 获取ArrayIndexOutOfBound:1异常
- Multi_thread--Linux下多线程编程中信号量介绍及简单使用
- siesta在Linux运行,siesta-3.0-b
- mysql的Innodb为什么使用B+树
- python--继承
- 卢伟冰正式预告Redmi K30:首发双开孔全面屏+双模5G
- arcgis 批量计算几何_ArcGIS数据统计
- Java-类和对象、关键字、构造方法
- ccd后视摄像头_预计2021年全球车载摄像头总出货将达到1.43亿颗
- QML Item 核心元素
- VM Workstation 12.0+ 参考序列号及linux系统推荐
- PMP培训内容有哪些?都要仔细看!
- android 二选一的按钮,选择框 RadioButton/Check - Android 入门教程
- 优达学诚--对安然事件数据集的分析
- 专升本英语——应试题型突破——阅读理解——阅读理解概述【学习笔记】
热门文章
- 基于Java的开源3D游戏引擎jMonkeyEngine
- CS224N课程学习笔记
- 13、微信小程序:上传图片到服务器
- #叉积#zoj 1041 poj 1106 ssl 1232 雷达覆盖问题 Transmitters
- Scratch(四十九):女神节快乐
- 《数学建模与数学实验》第5版 数据的统计描述 习题8.7
- Android开发之数据库更新失败原因分析
- 使用InnoSetup打包安装程序
- phpstorm ftp连不上 flashfxp 显示 PORT 模式连接成功
- plsql oracle默认用户名和密码,PLSQL Developer登录的默认密码介绍