这里的位数分离指的是:将一个数每个位数上的数字分离出来,进行操作。
在代码题中可能会用到这种方法,接下来我会通过例题和代码操作进行我个人对其的理解。
#include
int main()
{
int n = 0;
int num = 1; // 记录位数的变量
scanf("%d", &n);
int temp = n; // 利用临时变量接收
while (temp /= 10)
num++;
printf("%d\n", num);
return 0;
}
num变量 初始化为1是因为个位数在除以10后为0,在后面的 temp /= 10 等价于 temp = temp / 10,当temp为0时跳出循环,反之num++并再次进入循环去掉已被记录的位数,其只能记录十位数及以上的位数。用temp临时变量 来操作仅仅是我的个人习惯,这题可以直接用n来除以10。
这一题截取于牛客网的题目BC87 数位之和
#include
int main()
{
int n;
scanf("%d", &n);
int sum = 0; // 计算和
for (int temp = n; temp; temp /= 10) // 位数分离
{
int a = temp % 10; // 将当前位数上的数保存
sum += a; // 求和
}
printf("%d\n", sum);
return 0;
}
这一题将位数分离用的while循环改为了for循环。
此题要注意的是99有两个数字9。
#include
int main()
{
int num = 0; // 记录此数出现的次数
for (int i = 1; i < 100; i++) // 遍历1到99
{
for (int temp = i; temp; temp /= 10) // 对当前的数 位数分离
{
int a = temp % 10; // 保留当前位数上的数
if (a == 9) // 记录为数字9的数
num++;
}
}
printf("%d\n", num);
return 0;
}
例如:
输入:
12345
输出:
5
40
300
2000
10000
输入:
987654321
输出:
1
20
300
4000
50000
600000
7000000
80000000
900000000
#include
#include
int main()
{
int n;
scanf("%d", &n);
for (int temp = n, i = 0; temp; temp /= 10, i++) // 将位数分离与次方i合并
{
int a = temp % 10; // 保留当前位数上的数
printf("%d\n", a * (int)pow(10, i)); // 使用pow函数将每个数对应在自己的位数上
}
return 0;
}
通过上面的题目我们可以知道,使用位数分离在一些需要对自身位数上的数操作时的题目是一个不错的选择。那接下来我们去牛客网上寻找一些类似的题看能否实现。
这题取自于牛客网BC91 水仙花数
#include
int main()
{
int n, m;
while (scanf("%d %d", &n, &m) == 2)
{
int exist = 0;
for (int i = n; i <= m; i++) // 遍历n到m中的数
{
int sum = 0; // 保存立方和
for (int temp = i; temp; temp /= 10) // 位数分离
sum += (temp % 10) * (temp % 10) * (temp % 10);
if (i == sum) // 判断是否相等
exist = printf("%d ", sum);
}
if (!exist) // 不存在的情况
printf("no");
}
return 0;
}
水仙花数这一经典题也可以使用位数分离。
这题取自于牛客网BC92 变种水仙花
#include
#include
int main()
{
for (int i = 1e4; i < 1e5; i++)
{
int sum = 0;
for (int j = 1; j <= 4; j++)
{
int left = i / (int)pow(10, j); // 将左半分离
int right = i % (int)pow(10, j); // 将右半分离
sum += left * right; // 计算两者的乘积
}
if (i == sum)
printf("%d ", i);
}
return 0;
}
通过观察发现上式pow函数与j次方可以用j = 10, j *= 10来替换,还可以把right和left计算的过程直接放在sum计算中,则可以这样写:
#include
int main()
{
for (int i = 1e4; i < 1e5; i++)
{
int sum = 0;
for (int j = 10; j <= 1e4; j *= 10)
sum += (i / j) * (i % j); // 计算两者的乘积
if (i == sum)
printf("%d ", i);
}
return 0;
}
这题取自于牛客网BC97 回文对称数
#include
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for (int i = 1; i <= n; i++)
{
int sum = 0;
for (int temp = i; temp; temp /= 10)//将原来的数 倒置
sum = sum * 10 + temp % 10 ;
if (i == sum) // 判断
printf("%d\n", i);
}
}
return 0;
}
#include
#include
int main()
{
for (int i = 1; i <= 1e6; i++)
{
int sum = 0;
int n = 0;
for (int temp = i; temp; temp /= 10) // 计算位数
n++;
for (int temp = i; temp; temp /= 10) // 当前位数的幕
sum += (int)pow((temp % 10), n);
(i == sum) ? printf("%d ", i) : 0; // 打印
}
return 0;
}
描述:
输入一个十进制的数(1~1000),再输入十以内的一个进制,将十进制的数转化为该进制并打印。
例如:
输入:
10
2
输出:
1010
输入:
9
9
输出:
10
#include
int main()
{
int n, num1;
scanf("%d", &n);
scanf("%d", &num1);
int sum1 = 0;
for (int temp = n, i = 1; temp; temp /= num1/*想要转化的进制*/, i *= 10/*当前进制*/)
sum1 += temp % num1/*想要转化的进制*/ * i;
printf("%d\n", sum1);
return 0;
}
使用位数分离时应该结合题目条件,要准备好位数分离的对象和位数分离后的代码连接与配合。
以上是我对位数分离的理解,如果文章有错误还请联系我,我会更改的。
谢谢阅读