题目:
找到满足条件的数组
给定函数d(n)=n+n的各位之和,n为正整数,如d(78)=78+7+8=93。这样这个函数可以看成一个生成器,如93可以看成由78生成。
定义数A:数A找不到一个数B可以由d(B)=A,即A不能由其他数生成。现在要写程序,找出1至10000里的所有符合数A定义的数。
回答:
申请一个长度为10000的bool数组,每个元素代表对应的值是否可以有其它数生成。开始时将数组中的值都初始化为false。
由于大于10000的数的生成数必定大于10000,所以我们只需遍历1到10000中的数,计算生成数,并将bool数组中对应的值设置为true,表示这个数可以有其它数生成。
最后bool数组中值为false的位置对应的整数就是不能由其它数生成的。
---------------------------------------------------------
我尝试用解方程的思路来看一下:
先把问题的范围缩小到: 找出1至1000里的所有符合数A定义的数, (为了便于表达, 定义数A构成一个集合SA, SA的补集为RA)
对于小于1000的正整数n(n的各位用ni表示), 有: n = n0 + n1 * 10 + n2 * 10^2 = ∑ni * 10^i ; i∈{0~2}, ni∈{0~9}
考察函数 y ≡ f(n, x) = n2 * x^2 + n1 * x + n0; (x = 10, 因为是十进制数)
其中, 向量n=(n2, n1, n0), ni∈{0~9}, i∈{0~2};
上述问题里的d(n) = n + ∑ni = f(n, x)+ ∑ni; (x = 10)
对于1至1000里的正整数N, 如果存在另一个正整数n, 使得d(n) = N, 那么N∈RA; 反之, 如果找不到另一个正整数n, 使得d(n) = N, 那么N∉SA. .
考察方程(1): d(n) - N = 0; (即: n2 * x^2 + n1 * x + n0 + (n2 + n1 +n0) - N = 0) ..............(1)
如果把方程(1)看做是关于x的方程, 那么问题变为: 当ni和N取哪些正整数时, 方程(1)至少有一个值为10的根.
根据二次方程(A*x^2 + B*x +C = 0)求根公式:
x0 = (-b + sqrt(Δ)/(2a), x1 = (-b - sqrt(Δ)/(2a);
Δ = B^2 - 4AC;
A = n2;
B = n1;
C = n0 + (n2 + n1 +n0) - N;
当x = 10时, 得到N, ni的关系式:
N = 101*n2 + 11*n1 + 2*n0; ...........................(2)
这与1~1000时找N的方法是一致的.
现在考察问题范围扩大至1~10000, 这时就要涉及三次方程求根的方法了. 看看能得到什么结果
参考盛金公式:
总判别式Δ=B2-4AC
盛金判别法:
考察函数 y ≡ f(n, x) = n3 * x^3 + n2 * x^2 + n1 * x + n0; (x = 10, 因为是十进制数)
考察方程(3): d(n) - N = 0; (即: n3 * x^3 + n2 * x^2 + n1 * x + n0 + (n3 + n2 + n1 +n0) - N = 0) ..............(3)
由盛金公式得:
a = n3; b = n2; c = n1; d = n0 + (n3 + n2 + n1 +n0) - N = (n3 +n2 +n1 +2*n0 -N);
A = b^2 - 3ac = n2^2 - 3*n3*n1;
B = bc - 9ad = n2*n1 - 9* n3*(n3 + n2 + n1 +2*n0 - N);
C = c^2 - 3bd = n1^2 - 3* n2* (n3 + n2 + n1 +2*n0 - N);
Δ = B^2 - 4AC;
盛金判别法:
令x1 = x2 = x3 = 10, 得:
30a +b = 0;......(1.1)
10b +c = 0;......(1.2)
10c +3d = 0;......(1.3)
同时, A=0, B=0;得:
b^2 - 3ac = 0;......(1.4)
bc - 9ad = 0;......(1.5)
连立方程组得:
N = 2*n0 + 1271*n3;
考虑到a, b,c都是正整数, 实际上可从(1.1), (1.2), (1.3) 得出a=b=c=0, 这和a≠0的假设矛盾, 所以这种情况下没有我们想要的数.
哎, 结果不就是个 N = 1001*n3 + 101*n2 + 11*n1 + 2*n0嘛; 看来用解方程的方法还是绕远了啊,