提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


题目

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。

例如:给定一个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进制数,得到了整个问题的解。经过分析,这道题综合性很强,每一小步都需要一些思考和总结,在做完题目的时候真的需要及时复盘,这样才能更好的进步。就写到这里了,祝学习进步!

北理乐学回文数的思考(附代码)相关推荐

  1. C语言判断一个数是否是回文数Palindrome算法(附完整源码)

    判断回文数Palindrome的算法 判断回文数Palindrome的算法完整源码(定义,实现,main函数测试) 判断回文数Palindrome的算法完整源码(定义,实现,main函数测试) #in ...

  2. python判断是否回文_对python判断是否回文数的实例详解

    设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称n为一回文数:但若n=1234567,则n不是回文数. 上面的解释就是说回文数和逆 ...

  3. python怎么设置回文数_python如何写一个函数判断回文数?

    python如何写一个函数判断回文数? python写一个函数判断回文数的方法: 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称 ...

  4. 20200119:(leetcode)回文数(3种解法)

    回文数 题目 基本思路 代码实现 题目 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -1 ...

  5. 判断一个整数是否是回文数

    2019独角兽企业重金招聘Python工程师标准>>> 这段代码是我做leetcode练习题时写的,虽然实现了回文数的识别,但是倒置后的数字不是一个完整的数字,而是由几个输出拼接而成 ...

  6. java如何判断回文数

    java如何判断回文数 什么是回文数?数值两边呈对称的数是回文数,比如121,12321,1234321- 但是回文数应该怎么判断呢,以121举例子: 121%(取余)10得到了1, 12%10得到了 ...

  7. 判断一个整数是否为回文数

    一.题目描述 二.思路 (1)可以将该整数转换成字符串,根据字符串的长度奇偶性来确定中间位置,然后首尾进行对比是否是回文数字.此时需要额外空间来存储字符串,然后进行判断 (2)可以将整数的最后一半数字 ...

  8. python回文数判定_python如何写一个函数判断回文数?

    python如何写一个函数判断回文数? python写一个函数判断回文数的方法: 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称 ...

  9. 判断回文数的两种解法

    一.首先什么是回文数呢? "回文"是指正读反读都能读通的句子,它是古今中外都有的一种修辞方式和文字游戏,如"我为人人,人人为我"等.在数学中也有这样一类数字有这 ...

最新文章

  1. 查找谁在使用文件系统
  2. mysql负载均衡与同步_MySql数据库从同步负载均衡实时备份
  3. 能力素质有所欠缺_孩子说话啰嗦没重点?家长学会“大脑整理术”,提高孩子表达能力...
  4. Qt中的TCP客户端编程
  5. Mybatis:基于注解形式,传入List,返回List实体
  6. java arraybound out_java – 获取ArrayIndexOutOfBound:1异常
  7. Multi_thread--Linux下多线程编程中信号量介绍及简单使用
  8. siesta在Linux运行,siesta-3.0-b
  9. mysql的Innodb为什么使用B+树
  10. python--继承
  11. 卢伟冰正式预告Redmi K30:首发双开孔全面屏+双模5G
  12. arcgis 批量计算几何_ArcGIS数据统计
  13. Java-类和对象、关键字、构造方法
  14. ccd后视摄像头_预计2021年全球车载摄像头总出货将达到1.43亿颗
  15. QML Item 核心元素
  16. VM Workstation 12.0+ 参考序列号及linux系统推荐
  17. PMP培训内容有哪些?都要仔细看!
  18. android 二选一的按钮,选择框 RadioButton/Check - Android 入门教程
  19. 优达学诚--对安然事件数据集的分析
  20. 专升本英语——应试题型突破——阅读理解——阅读理解概述【学习笔记】

热门文章

  1. 基于Java的开源3D游戏引擎jMonkeyEngine
  2. CS224N课程学习笔记
  3. 13、微信小程序:上传图片到服务器
  4. #叉积#zoj 1041 poj 1106 ssl 1232 雷达覆盖问题 Transmitters
  5. Scratch(四十九):女神节快乐
  6. 《数学建模与数学实验》第5版 数据的统计描述 习题8.7
  7. Android开发之数据库更新失败原因分析
  8. 使用InnoSetup打包安装程序
  9. phpstorm ftp连不上 flashfxp 显示 PORT 模式连接成功
  10. plsql oracle默认用户名和密码,PLSQL Developer登录的默认密码介绍