解决一道逻辑题

因为S知道两个数的和,但推断P不知道两个数,所以两个数S的和一定不能拆分成两个素数的和,即M和N不可能都是素数,M和N中也不会有大于50的素数,否则m*n可以唯一分解,P知道M和N的乘积就可以知道M和N。

p从S的发言中可以判断出的信息是:

1。m和n不会都是质数;

2。m和n中不会有大于50的质数;

3。m和n的和不能除以两个素数的和;

4。因为S不知道这两个数是什么,所以这两个数之和必须小于99+98,否则S就能知道这两个数是什么。

满足上述条件的S=m+n有以下可能性:

11

17

23

27

29

35

37

41

47

196

然后p马上根据他掌握的p=m*n计算m和n,说明p=m*n是一个特殊的数,具有以下性质:

根据这个特殊的P,当S取上述值时,只有一个S值使方程成立

m+n=s,

m*n=p

中有一个唯一的整数解。

根据这一性质计算的p有以下条件(设m

p = 18,s= 11,m = 2,n = 9

p = 24,s= 11,m = 3,n = 8

p = 28,s= 11,m = 4,n = 7

p = 50,s= 27,m = 2,n = 25

p = 52,s= 17,m = 4,n = 13

p = 54,s= 29,m = 2,n = 27

p = 76,s= 23,m = 4,n = 19

p = 92,s= 27,m = 4,n = 23

p = 96,s= 35,m = 3,n = 32

p = 100,s= 29,m = 4,n = 25

p = 110,s= 27,m = 5,n = 22

p = 112,s= 23,m = 7,n = 16

p = 114,s= 41,m = 3,n = 38

p = 124,s= 35,m = 4,n = 31

p = 130,s= 23,m = 10,n = 13

p = 138,s= 29,m = 6,n = 23

p = 140,s= 27,m = 7,n = 20

p = 148,s= 41,m = 4,n = 37

p = 150,s= 35,m = 5,n = 30

p = 152,s= 27,m = 8,n = 19

p = 154,s= 29,m = 7,n = 22

p = 160,s= 37,m = 5,n = 32

p = 162,s= 27,m = 9,n = 18

p = 168,s= 29,m = 8,n = 21

p = 170,s= 27,m = 10,n = 17

p = 172,s= 47,m = 4,n = 43

p = 174,s= 35,m = 6,n = 29

p = 176,s= 27,m = 11,n = 16

p = 182,s= 27,m = 13,n = 14

p = 186,s= 37,m = 6,n = 31

p = 190,s= 29,m = 10,n = 19

p = 196,s= 35,m = 7,n = 28

p = 198,s= 29,m = 11,n = 18

p = 204,s= 29,m = 12,n = 17

p = 208,s= 29,m = 13,n = 16

p = 216,s= 35,m = 8,n = 27

p = 232,s= 37,m = 8,n = 29

p = 234,s= 35,m = 9,n = 26

p = 238,s= 41,m = 7,n = 34

p = 246,s= 47,m = 6,n = 41

p = 250,s= 35,m = 10,n = 25

p = 252,s= 37,m = 9,n = 28

p = 270,s= 37,m = 10,n = 27

p = 276,s= 35,m = 12,n = 23

p = 280,s= 47,m = 7,n = 40

p = 288,s= 41,m = 9,n = 32

p = 294,s= 35,m = 14,n = 21

p = 304,s= 35,m = 16,n = 19

p = 306,s= 35,m = 17,n = 18

p = 310,s= 41,m = 10,n = 31

p = 322,s= 37,m = 14,n = 23

p = 336,s= 37,m = 16,n = 21

p = 340,s= 37,m = 17,n = 20

p = 348,s= 41,m = 12,n = 29

p = 364,s= 41,m = 13,n = 28

p = 370,s= 47,m = 10,n = 37

p = 378,s= 41,m = 14,n = 27

p = 390,s= 41,m = 15,n = 26

p = 396,s= 47,m = 11,n = 36

p = 400,s= 41,m = 16,n = 25

p = 408,s= 41,m = 17,n = 24

p = 414,s= 41,m = 18,n = 23

p = 418,s= 41,m = 19,n = 22

p = 442,s= 47,m = 13,n = 34

p = 462,s= 47,m = 14,n = 33

p = 480,s= 47,m = 15,n = 32

p = 496,s= 47,m = 16,n = 31

p = 510,s= 47,m = 17,n = 30

p = 522,s= 47,m = 18,n = 29

p = 532,s= 47,m = 19,n = 28

p = 540,s= 47,m = 20,n = 27

p = 546,s= 47,m = 21,n = 26

p = 550,s= 47,m = 22,n = 25

p = 552,s= 47,m = 23,n = 24

p = 9604,s= 196,m = 98,n = 98

最后,在P说已经知道M和N之后,S也说知道M和N,这说明S可以从手里的两个数之和推断出唯一的M和N。

因此,需要去掉上述情况中S的重复使用,得到如下情况:

p = 52,s = 17,m = 4,n = 13

p = 9604,s = 196,m = 98,n = 98

如果m

m=4,n=13

程序如下:

# include & ltiostream.h & gt

# include & ltfstream.h & gt

# include & ltstring.h & gt

const int MAX _ N = 99

const char * OUTPUT _ FILE = " result . txt ";

int s[MAX _ N * 2];

int p[MAX _ N * MAX _ N];

int prim[MAX _ N];

int prim counter = 0;

ofstream fout(输出文件);

//计算质数

void calPrim()

{

使用了bool[MAX _ N];

int i,p = 2;

bool found = true

prim[prim counter++]= 2;

memset( used,false,sizeof(used));

while(发现){

for(I = p;我& ltMAX _ N;i++)

如果(i % p == 0)

used[I]= true;

发现=假;

for(I = p;我& ltMAX _ N;i++)

如果(!已用[i] ) {

p = I;

prim[prim counter++]= p;

发现=真;

打破;

}

}

}

//根据条件1过滤

void useCon_1()

{

int i,j;

memset(s,0,sizeof(s));

for(I = 0;我& lt4;i++)s[I]=-1;

cal prim();

// S可以确定P不知道这两个数是什么。

for(I = 0;我& ltprimCounteri++)

for(j = I;j & ltprimCounterj++ ) {

if(prim[I]+prim[j]& lt;MAX_N * 2)

s[prim[I]+prim[j]]=-1;

}

for(I = 0;我& ltprimCounteri++)

if(prim[I]& gt;MAX _ N/2)break;

for(I-;我& ltprimCounteri++)

for(j = 2;j & ltMAX _ N;j++)

s[prim[I]+j]=-1;

//因为S不知道这两个数是什么。

for(I = 98+99;我& ltMAX _ N+MAX _ N;i++)

s[I]=-1;

fout & lt& lt"求S的第一句中两个数的和. "

for(I = 0;我& ltMAX _ N * 2;i++)

if( s[i] == 0)

fout & lt& lt我& lt& ltendl

}

//根据条件2过滤

void useCon_2()

{

int i,m,n;

memset( p,0,sizeof(p));

for(m = 2;m & ltMAX _ N;m++)

for(n = 2;n & ltMAX _ N;n++ ) {

if(s[m+n]& gt;= 0 ) {

p[m * n]++;

}

}

fout & lt& lt"满足P的第一句的两个数的乘积:"

for(I = 0;我& ltMAX _ N * MAX _ Ni++)

if( p[i] == 1 || p[i] == 2 ) {

for(m = 2;m & ltMAX _ N;m++)

for(n = m;n & ltMAX _ N;n++)

if(m * n = = I & amp;& amps[m+n]& gt;= 0 ) {

fout & lt& lt" p = " & lt& lt我

& lt& lt",s = " & lt& ltm + n

& lt& lt“,m = " & lt& ltm

& lt& lt“,n = " & lt& ltn & lt& ltendl

s[m+n]++;

}

}

}

void useCon_3()

{

int i,m,n;

fout & lt& lt"满足S的第二句的结果:"

for(I = 0;我& ltMAX _ N * MAX _ Ni++)

if( p[i] == 1 || p[i] == 2 ) {

for(m = 2;m & ltMAX _ N;m++)

for(n = m;n & ltMAX _ N;n++)

if(m * n = = I & amp;& amps[m + n] == 1 ) {

fout & lt& lt" p = " & lt& lt我

& lt& lt",s = " & lt& ltm + n

& lt& lt“,m = " & lt& ltm

& lt& lt“,n = " & lt& ltn & lt& ltendl

}

}

}

void main()

{

useCon _ 1();

useCon _ 2();

useCon _ 3();

}