c++ - 用算法查找回文
问题描述
我得到一个数字 N<=200,我需要仅使用此算法找到回文并输出回文和迭代次数:
1) 倒数
2)倒数+前一
例子:
1) N=99
出 99 0
2) N=69
69+96=165 165+561=726 726+627=1353 1353+3531=4884
出:4884 4
我的代码:
#include <iostream>
using namespace std;
int rev(int a)
{
int b = 0;
while (a)
{
b = 10 * b + a % 10;
a /= 10;
}
return b;
}
int main()
{
ios::sync_with_stdio(0);
int n, c = 0;
cin >> n;
while (n != rev(n))
{
n = n + rev(n);
c++;
}
cout << n << endl << c;
return 0;
}
它仅适用于 100 个测试中的 70 个:(
你能帮我使它适用于所有测试吗?
解决方案
这只是整数溢出的问题。第一个实现是用 unsigned long long 实现的。它似乎有效,但未检测到一些溢出。
使用 __int128 执行了新的实现。此外,使用签名版本以便能够轻松检测溢出。
现在,对于介于 1 和 200 之间的 n,所有回文都被找到,除了 n = 196,它检测到溢出。
这是程序:
#include <iostream>
//using namespace std;
void print128 (__int128 a) {
__int128 v64 = (__int128) 1 << 64;
__int128 high128 = a / v64;
__int128 low128 = a % v64;
unsigned long long high = high128;
unsigned long long low = low128;
if (high > 0) std::cout << high;
std::cout << low;
}
__int128 rev(__int128 a) {
__int128 b = 0;
while (a) {
b = 10 * b + a % 10;
a /= 10;
}
return b;
}
int main() {
//std::ios::sync_with_stdio(0);
int nerr = 0;
int cmax = 100000;
for (int n0 = 10; n0 <= 200; n0++) {
bool overf = false;
int c = 0;
__int128 nrev;
__int128 n = n0;
while ((n != (nrev = rev(n))) && (c < cmax)) {
if (nrev < 0) overf = true;
n = n + nrev;
if (n < 0) overf = true;
c++;
}
std::cout << "n = " << n0 << " ";;
if ((c == cmax) && !overf) {
std::cout << " ERR0R\n";
nerr++;
} else if (overf) {
std::cout << " OVERFLOW\n";
nerr++;
} else {
std::cout << " palym = ";
print128 (n);
std::cout << " c = " << c << "\n";
}
}
std::cout << "Nbre of errors = " << nerr << "\n";
return 0;
}
问题是“196案怎么办?” 我们不知道是否存在解决方案,即是否存在收敛。此外,如果它收敛,我们不知道回文的大小可能是多少。尝试使用int
更多位可能是一场漫长的比赛。更好的方法是实现一个专门的 int 类型来适应这个问题,即一个 int 向量,每个 int 介于 0 和 9 之间。对于这个算法,我们只需要执行两个操作,计算回文和加法。计算回文将是微不足道的,反转向量的元素(忽略第一个零),并且加法将很容易实现。此外,这样的添加将很容易检测到溢出。最后但并非最不重要的一点是,向量的大小可以针对每个n
值进行调整,直到给定限制。
编辑:在评论中,Mark Ransom 提供了关于 Lychrel 数字的维基百科页面的链接,即算法不会收敛的数字。196是最低和最著名的“候选人莱克瑞尔”号码。196 是这样一个数字,只是推测而不是证明。已经进行了数十亿位数的实验,但没有找到这个数字的收敛性。
推荐阅读
- android - 运行应用程序时如何修复应用程序:processDebugResources?
- java - Java 中的 Select 语句因错误而终止
- vue.js - 无法在mounted() hook Nuxt.js 中从Vuex 商店调度方法
- reactjs - 通过 react-image-crop 模块获取裁剪图像
- azure - Kudu 调试控制台 Bash vs SSH
- javascript - 如何使用 Google My Business API 获取位置列表
- vue.js - Two compile cases with Webpack, Vue.js, and Sass
- google-sheets - 在 ArrayFormula Google 表格中使用 SUMIFS
- php - 如何使用 php 在微软企业帐户中以可编辑格式打开文档?
- macos - 在 Mac OS high Sierra 上设置 KaiOS 环境