C++ 程序 计算可被8整除的旋转次数
给定一个作为字符串的大正数,计算该数字的所有旋转中可被8整除的数字数量。
举例:
输入:8
输出:1
输入:40
输出:1
旋转:40可被8整除
04不可被8整除
输入:13502
输出:0
无旋转能被8整除
输入:43262488612
输出:4
方法: 对于较大的数字,难以将其旋转并将每个数字除以8。因此,使用了“可被8整除”的属性,该属性表明如果数字的最后3个数字可被8整除,则数字可被8整除。在此处,我们不实际旋转数字并检查最后8位数字是否可被整除,而是计算由3个数字(以环形方式)组成的连续序列,这些连续序列可被8整除。
示范:
考虑数字928160
其 旋转 为928160、092816、609281、
160928、816092、281609。
现在按照所述方法从原始数字928160开始形成连续的3位数序列。
3位数: (9,2,8),(2,8,1),(8,1,6),
(1,6,0),(6,0,9),(0,9,2)
我们可以观察到,这些集合所形成的3位数,即928、281、816、160、609、092,
都出现在某些旋转的最后3位数字中。
因此,检查这些3位数是否可被整除就可以得到所需的旋转次数。
// C++程序:计算所有可被8整除的旋转次数
#include <bits/stdc++.h>
using namespace std;
// 计算所有可被8整除的旋转次数
int countRotationsDivBy8(string n)
{
int len = n.length();
int count = 0;
// 对于单个数字的情况
if (len == 1) {
int oneDigit = n[0] - '0';
if (oneDigit % 8 == 0)
return 1;
return 0;
}
// 对于两位数字(考虑所有数对)
if (len == 2) {
// 第一组数对
int first = (n[0] - '0') * 10 + (n[1] - '0');
// 第二组数对
int second = (n[1] - '0') * 10 + (n[0] - '0');
if (first % 8 == 0)
count++;
if (second % 8 == 0)
count++;
return count;
}
// 考虑所有的三位数序列
int threeDigit;
for (int i = 0; i < (len - 2); i++) {
threeDigit = (n[i] - '0') * 100 +
(n[i + 1] - '0') * 10 +
(n[i + 2] - '0');
if (threeDigit % 8 == 0)
count++;
}
// 考虑由最后一位数字和前两个数字组成的数字
threeDigit = (n[len - 1]- '0') * 100 +
(n[0] - '0') * 10 +
(n[1] - '0');
if (threeDigit % 8 == 0)
count++;
// 考虑由最后两个数字和第一个数字组成的数字
threeDigit = (n[len - 2] - '0') * 100 +
(n[len - 1] - '0') * 10 +
(n[0] - '0');
if (threeDigit % 8 == 0)
count++;
// 所需的旋转次数
return count;
}
// 主程序以测试上述函数
int main()
{
string n = "43262488612";
cout << "旋转次数: "
<< countRotationsDivBy8(n);
return 0;
}
输出:
旋转次数: 4
时间复杂度: O(n),其中 n 是输入数字的位数。
辅助空间复杂度: O(1)