文章目录
题目
[NOIP1999]回文数 链接: link
思路
因为至多可能会进行30次加法,所以最终的数字长度很有可能会超过int类型的最大范围,导致溢出,所以我们采用数组的方式记录数字。
c
int n;
scanf("%d", &n);//读取进制
char m[200] = { 0 };//因为之多会进行30次循环,所以,最后数字的大小可能会很大,所以我们可以通过创建一个足够长的数组来存储
scanf("%s", &m);//读取回文数
这道题中判断是否进行下一次加法的一句就是当前数是否为回文数,所以我们先自定义一个可以判断是否为回文数的函数 is_huiwen(char* m) ,并且通过输出来判断是否为回文数
c
int is_huiwen(char* m)//判断是否为回文数,是返回1,否返回0
{
for (int i = 0; i < strlen(m); i++)
{
if (m[i] != m[strlen(m) - 1 - i])
return 0;
}
return 1;
}
自定义 sum 函数,进行回文数相加操作
但是这个过程中有很多点需要注意
- 传进去是字符串的形式,我们可以利用自定义函数 ctio 转换为整形后进行加法,最后再用自定义函数 itoc 转换为字符输出
- 加法后的数字位数很有可能与之前不同,所以我们可以创建一个新的数组来储存加法后的数字,最后倒回去。
- 加法过程中存在仅为,需要提前设置 jw 来辅助
c
int ctoi(char x)//字符转int
{
int y = 0;
if (x >= 'A' && x <= 'E')
{
y = x - 'A' + 10;
}
if (x >= '0' && x <= '9')
{
y = x - '0';
}
return y;
}
char itoc(int x)//int转字符
{
char y;
if (x < 10) y = x + '0';
else y = x - 10 + 'A';
return y;
}
void sum(char* m,int n)//计算x进制加法,把结果覆盖到m数组中
{
char sum[200] = { 0 };//sum记录顺序最左边为个位.
int len = strlen(m), i, jw = 0;//使用jw来记录进位情况
for (i = 0; i < len; i++)
{
int x, y;
x = ctoi(m[i]);
y = ctoi(m[len - i - 1]);
int s = x + y;
sum[i] = itoc((s + jw) % n);
jw = (s + jw) / n;
}
if (jw != 0) sum[i] = itoc(jw);//最后一位进位
len = strlen(sum);
for (i = 0; i < len; i++)//覆盖m
{
m[i] = sum[len - i - 1];
}
}
代码呈现
c
#include<stdio.h>
#include<assert.h>
#include<string.h>
int ctoi(char x) { //字符转int
int y = 0;
if (x >= 'A' && x <= 'E') {
y = x - 'A' + 10;
}
if (x >= '0' && x <= '9') {
y = x - '0';
}
return y;
}
char itoc(int x) { //int转字符
char y;
if (x < 10) y = x + '0';
else y = x - 10 + 'A';
return y;
}
void sum(char* m, int n) { //计算x进制加法,把结果覆盖到m数组中
char sum[200] = { 0 };//sum记录顺序最左边为个位.
int len = strlen(m), i, jw = 0;//使用jw来记录进位情况
for (i = 0; i < len; i++) {
int x, y;
x = ctoi(m[i]);
y = ctoi(m[len - i - 1]);
int s = x + y;
sum[i] = itoc((s + jw) % n);
jw = (s + jw) / n;
}
if (jw != 0) sum[i] = itoc(jw);//最后一位进位
len = strlen(sum);
for (i = 0; i < len; i++) { //覆盖m
m[i] = sum[len - i - 1];
}
}
int is_huiwen(char* m) { //判断是否为回文数,是返回1,否返回0
for (int i = 0; i < strlen(m); i++) {
if (m[i] != m[strlen(m) - 1 - i])
return 0;
}
return 1;
}
int main() {
int n;
scanf("%d", &n);//读取进制
char m[200] = { 0 };//因为之多会进行30次循环,所以,最后数字的大小可能会很大,所以我们可以通过创建一个足够长的数组来存储
scanf("%s", &m);//读取回文数
int count = 0;
while (count < 31) {
if (is_huiwen(
m)) { //判断当前是否为回文数,如果是回文数,就直接退出
break;
} else {
sum(m, n);
count++;
}
}
if (count == 31)
printf("Impossible!");
else
printf("STEP=%d", count);
return 0;
}