[环境:Windows8.1 + Dev-c++5.11]
3n+1猜想即为卡拉兹(Callatz)猜想:
3x+1 ······ ①
x / 2 ······ ②
一个方程组, 对于任意正整数 x
如果它是奇数则执行①;
如果它是偶数则执行②;
我们编写一个程序验证一定范围以内的 n 成立。
枚举从 1 到 MAX_N 逐一验证。
#include <cstdio>
#include <vector>
#include <algorithm>
#include <conio.h>
#define MAX_STEP 1e6
using namespace std;
int main() {
unsigned long long i = 1, limit, price;
bool flag = 0;
vector<unsigned long long> nerror;
printf("limit number: ");
scanf("%lld", &limit);
price = limit / 100;
FILE *ferr = fopen("3n+1_error.log", "w");
printf("Checking 3n+1 from 1 to %lld... 00%%", limit);
for (; i <= limit; ++i) {
unsigned long long num = i, step = 0;
while (num != 1) {
if (num % 2) num = num * 3 + 1;
else num /= 2;
if (num < i) {
if (!flag) break;
}
if (step++ > MAX_STEP) {
nerror.push_back(i);
fprintf(ferr,
"[Error] number %lld isn't correct! (now is %lld)\n",
i,
num);
flag = 1;
break;
}
}
printf("\b\b\b%02d%%", (int)(i / price));
}
printf("\b\b\b\bdone.\n");
if (flag) printf("\n\nBut there is some error. see \"3n+1_error.log\"\n");
getch();
return 0;
}
效率较低:
发现CPU占用率并不高, 许多CPU资源被白白浪费了:
线程可以提高占用率,加快验证速度:
#include <thread>
#include <cstdio>
#include <vector>
#include <conio.h>
#define MAX_STEP 10000000
#define MAX_THREAD 10
using namespace std;
FILE *ferr = fopen("3n+1_error+.log", "w");
unsigned long long cnt = 1;
int end_sign = 0;
bool flag = 0;
void check(unsigned long long start, unsigned long long end) {
unsigned long long i = start;
for (; i <= end; ++i) {
unsigned long long num = i, step = 0;
while ((num != 1)) {
if (num % 2) num = num * 3 + 1;
else num /= 2;
if (num < i) {
if (!flag) break;
}
if (step++ > MAX_STEP) {
fprintf(ferr,
"[Error] number %d isn't correct! (now is %d)\n",
i,
num);
flag = 1;
break;
}
}
++cnt;
}
++end_sign;
}
int main() {
unsigned long long limit, price, each;
printf("limit number: ");
scanf("%lld", &limit);
each = limit / MAX_THREAD + 1;
price = limit / 100;
printf("Checking 3n+1 from 1 to %lld... 00%%", limit);
thread t1(check, each * 0 + 1, each * 1);
thread t2(check, each * 1, each * 2);
thread t3(check, each * 2, each * 3);
thread t4(check, each * 3, each * 4);
thread t5(check, each * 4, each * 5);
thread t6(check, each * 5, each * 6);
thread t7(check, each * 6, each * 7);
thread t8(check, each * 7, each * 8);
thread t9(check, each * 8, each * 9);
thread t10(check, each * 9, each * 10);
for (;end_sign < MAX_THREAD;) {
printf("\b\b\b%02d%%", (cnt / price));
}
printf("\b\b\b\bdone.\n");
if (flag) printf("\n\nBut there is some error. see \"3n+1_error+.log\"\n");
getch();
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
t9.join();
t10.join();
return 0;
}
编译时可能要加上编译选项 -std=c++11
dev-c++ 可以在 工具 -> 编译选项 -> 编译时加入以下命令 添加
效率提高不少:
大家有兴趣可以验证一下,目前验证到最高应该是