-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,11 @@ | ||
# ReciprocalSearch | ||
在1到100中找10个不同的数,使其倒数和为1。从小到大排列这10个数,有一个不同就视为不同的解。求所有的解。 | ||
|
||
程序的原始版本不是我写的。 | ||
|
||
基本思路是用抽屉原则,确定每重循环/递归的搜索上限,进行剪枝。 | ||
比如:最开始的和是1,这个和需要分给10个数,那么至少有一个数分到的值是不小于1/10的,那么第一重循环的上限不大于10。 | ||
|
||
计算出来后,用大数运算库GMP校验一下,有71312个是对的(未去重)。校验的时候,第10个整数分别用(int)i10、(int)i10 + 1、(int)i10 - 1去尝试。 | ||
|
||
整个代码也可以不用double来运算,而是用GMP的自然数库来运算。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include <stdio.h> | ||
#include <math.h> | ||
|
||
#pragma warning(disable:4146) | ||
#include <gmp.h> | ||
|
||
#define min(a,b) (((a)<(b))?(a):(b)) | ||
|
||
bool check(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) { | ||
int a[10]; | ||
|
||
a[0] = i1; | ||
a[1] = i2; | ||
a[2] = i3; | ||
a[3] = i4; | ||
a[4] = i5; | ||
a[5] = i6; | ||
a[6] = i7; | ||
a[7] = i8; | ||
a[8] = i9; | ||
a[9] = i10; | ||
|
||
mpz_t t; | ||
mpz_init(t); | ||
mpz_set_ui(t, 1); | ||
for (int k = 0; k < 10; ++k) { | ||
mpz_mul_ui(t, t, a[k]); | ||
} | ||
|
||
mpz_t s; | ||
mpz_init(s); | ||
mpz_set_ui(s, 0); | ||
|
||
mpz_t t1; | ||
mpz_init(t1); | ||
for (int k = 0; k < 10; ++k) { | ||
mpz_div_ui(t1, t, a[k]); | ||
mpz_add(s, s, t1); | ||
} | ||
|
||
bool valid = (mpz_cmp(s, t) == 0); | ||
|
||
mpz_clear(t); | ||
mpz_clear(s); | ||
mpz_clear(t1); | ||
|
||
return valid; | ||
} | ||
|
||
int main() { | ||
int total = 0; | ||
int valid = 0; | ||
|
||
double ii[101]; | ||
|
||
for (int i = 1; i <= 100; i++) { ii[i] = 1.0 / i; } | ||
|
||
for (int i1 = 2; i1 <= 10; i1++) { | ||
double m1 = 1 - ii[i1]; | ||
|
||
for (int i2 = i1 + 1; i2 < min(92, (int)(9.0 / m1) + 1); i2++) { | ||
double m2 = m1 - ii[i2]; | ||
|
||
for (int i3 = i2 + 1; i3 < min(93, (int)(8.0 / m2) + 1); i3++) { | ||
double m3 = m2 - ii[i3]; | ||
if (m3 <= 0) { continue; } | ||
|
||
for (int i4 = i3 + 1; i4 < min(94, (int)(7.0 / m3) + 1); i4++) { | ||
double m4 = m3 - ii[i4]; | ||
if (m4 <= 0) { continue; } | ||
|
||
for (int i5 = i4 + 1; i5 < min(95, (int)(6.0 / m4) + 1); i5++) { | ||
double m5 = m4 - ii[i5]; | ||
if (m5 <= 0) { continue; } | ||
|
||
for (int i6 = i5 + 1; i6 < min(96, (int)(5.0 / m5) + 1); i6++) { | ||
double m6 = m5 - ii[i6]; | ||
if (m6 <= 0) { continue; } | ||
|
||
for (int i7 = i6 + 1; i7 < min(97, (int)(4.0 / m6) + 1); i7++) { | ||
double m7 = m6 - ii[i7]; | ||
if (m7 <= 0) { continue; } | ||
|
||
for (int i8 = i7 + 1; i8 < min(98, (int)(3.0 / m7) + 1); i8++) { | ||
double m8 = m7 - ii[i8]; | ||
if (m8 <= 0) { continue; } | ||
|
||
for (int i9 = i8 + 1; i9 < min(99, (int)(2.0 / m8) + 1); i9++) { | ||
double m9 = m8 - ii[i9]; | ||
|
||
if (m9 <= 0.01) { continue; } | ||
double i10 = 1.0 / m9; | ||
|
||
if (fabs(i10 - round(i10)) < 0.000001) { | ||
++total; | ||
|
||
if (check(i1, i2, i3, i4, i5, i6, i7, i8, i9, (int)i10)) { | ||
++valid; | ||
printf("%d %d %d %d %d %d %d %d %d %.4f(%d)\n", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, (int)i10); | ||
} else if (check(i1, i2, i3, i4, i5, i6, i7, i8, i9, (int)i10 + 1)) { | ||
++valid; | ||
printf("%d %d %d %d %d %d %d %d %d %.4f(%d)\n", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, (int)i10 + 1); | ||
} else if (check(i1, i2, i3, i4, i5, i6, i7, i8, i9, (int)i10 - 1)) { | ||
++valid; | ||
printf("%d %d %d %d %d %d %d %d %d %.4f(%d)\n", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, (int)i10 - 1); | ||
} | ||
else { | ||
printf("%d %d %d %d %d %d %d %d %d %.4f INVALID\n", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
printf("total %d, valid = %d\n", total, valid); | ||
} |