Bob 有两个正整数x,y(x<=y),把它们的和告诉了Susan,积告诉了Priscilla,并发生了如下对话:
Susan:我确定你不知道我的数是什么。
Priscilla:谢谢你,现在我知道了你的数字是S。
问S取[A,B]中哪些数可以合理的发生上述对话,且确定S的正整数x,y唯一。求这些数的和。
首先,假设Susan的数是m,她可以对推断Prisilla的数有这几种可能:1*(m-1), 2*(m-2),......。如果这些数每个都有两种以上的方法分解为两个数字的乘积,那么Susan便可以说:”我确定你不知道我的数是什么“。显然这些数除了1*(m-1),都肯定符合上一句话的条件,而1*(m-1)=m-1只有不为质数时,才符合这个条件。
结论1:x+y不等于某个质数+1。
然后再看,Priscilla的数应该不能为一个质数,因为若这个数为质数,那么它分解为两个数的乘积唯一,Susan就不能有她的推断。
结论2:x*y不是质数。
其次,假设Priscilla获得的乘积为n,n有若干种方法分解为两个质数的乘积:1*n, p1*q1, p2*q2,......。Priscilla可以推断Susan的数有下面这几种可能:1+n,p1+q1,p2+q2,......。应用结论1,这些数中有且只有1个不等于某个质数+1,Priscilla才可以说:”谢谢你,现在我知道了你的数字是S“,且这个数可以推断出原数x,y。且由结论2:n不是质数,可以知道,1+n不为某个质数+1,其它的数p1+q1,p2+q2,......均为某个质数+1,并且x=1,y=n。可以推出,如果Susan和Priscilla的对话合理,则可以解出x和y的唯一解,它们是x=1, y=S-1,即
结论3:x=1,y=n,且y不是质数,才有可能发生Susan和Priscilla的对话,且每个合理的S有唯一对应的x,y:x=1, y=S-1。
最后我们只需判断S是否合理皆可,Bob给他们的数肯定满足结论1、2、3,我们应找出所有的p、q满足p*q=S-1,即p*q=y,且p!=1, q!=S-1,如果每个p+q均为某个质数+1,那么S就合理,否则若有一组p+q!=质数+1,且1+n不为质数+1,那么Priscilla就没法唯一确定Sussan的数,故而该S不合理。实现中我们可以枚举p,q筛除不合理的S。
public class SumAndProductPuzzle {
public long getSum(int A, int B) {
long ans = 0;
boolean[] flag = new boolean[B+1];
boolean[] can = new boolean[B+1];
for (int i=2; i<=B; i++) {
if (flag[i] == false) {
for (int j=i+i; j<=B; j+=i)
flag[j] = true;
}
}
for (int i=3; i<=B; i++) {
if (flag[i-1] == true)
can[i] = true;
}
for (int i=2; i<=B; i++) {
for (int j=2; j<=i&&1+i*j<=B; j++) {
if (flag[i+j-1])
can[1+i*j] = false;
}
}
for (int i=A; i<=B; i++)
if (can[i])
ans += i;
return ans;
}
}