写程序看来是我破解无聊的最好的解药……

    早晨突然发现前些日子,某个酒足饭饱的午后,黄哥问的一个傻问题——当时也没有听清楚——居然是一道编程题!而且是很有难度的一道,呵呵,难得黄哥能问出这种问题!!决定解决之~~~~~~~~~~~~

    题目为(ACM/ICPC Regional Contest Southeastern European 2001. Problem C. Secret Numbers),原文如下:

Secret Numbers

Problem

Two natural numbers a and b are chosen (1<a<b). Person M is told the multiple of a and b (a*b), and person S is told the sum of a and b (a+b). The discussion between M and S goes like this:
M: I do not know the numbers a and b.
S: I do not know them either, but I knew you would not know them.
M: Now I know the numbers!
S: Now I know them, too!

Input

The input file contains pairs of natural numbers x and y (2<=x<y<=550), one pair per line. The input is guaranteed to be correct.

Output

For each pair x, y, find all pairs of a and b, such that x<=a<b<=y and that the given discussion is possible. Write these pairs in a single line, and finish that line with "no more pairs." if there are a and b found in the given range, or write simply "no pairs." if there are not. Separate the numbers of a pair with a comma, terminate each pair with a semi-colon, and separate different pairs with a blank after the semi-colon, as shown in the example below.

Sample Input

2 10
2 20

Output for the Sample Input

no pairs.
4,13; no more pairs.

简单解释一下:

    有两个数a和b(1<a<b)。M先生知道a*b的值,S先生知道a+b的值,两人有如下的对话:
      M先生:  我不知道a和b的值。
      S先生:  我也不知道,而且之前我还知道你不知道。
      M先生:  我现在知道a和b的值了。
      S先生:  我现在也知道a和b的值了。
    给定x和y(2<=x,y<=550),求所有满足对话场景的(a,b)且x<=a<b<=y。假设二位先生都足够聪明且没有撒谎!


你有想法了吗???


    幸好足够聪明的博得先生,在参考了N本书后,终于搞定了这个问题!下面来分析一记:

    解题的关键是MS两位先生的四句话,而且这四句话是步步递进的,也就是任何满足后一句的数对,必然满足前一句!如果可以将这四句话用四个逻辑判别函数( f1(a,b)~f4(a,b) )表示,就可以在给定的范围内求出所有的满足f4(a,b)的数对!

    首先,根据题意先设有两个集合:
        M(a,b)={ (x,y)| x*y=a*b 且 1<x<y }
        S(a,b)={ (x,y)| x+y=a+b 且 1<x<y }

    可以得到如下表格:

MS两位先生的话 实现函数 条件 返回值
M:我不知道a和b的值。 bool f1(int a,int b) |M(a,b)|>1 true

else

false
S:我也不知道,而且之前我还知道你不知道。 bool f2(int a,int b) 1、f1(a,b)==true
2、|S(a,b)|>1
3、任取(p,q)∈S(a,b)使得f1(p,q)==true
true

else

false
M:我现在知道a和b的值了。 bool f3(int a,int b) 1、f2(a,b)==true
2、只有一对(p,q)∈M(a,b)
满足f2(p,q)==true
true

else

false
S:我现在也知道a和b的值了。 bool f4(int a,int b) 1、f3(a,b)==true
2、只有一对(p,q)∈S(a,b)
满足f3(p,q)==true
true

else

false

    具体的实现就看代码吧!

足够聪明的博得先生!//ACM/ICPC Regional Contest Southeastern European 2001. 
足够聪明的博得先生!
//Problem C. Secret Numbers
足够聪明的博得先生!
//by BodeSmile 05.10.03
足够聪明的博得先生!
//
足够聪明的博得先生!
//        M(a,b)={ (x,y)| x*y=a*b 且 1<x<y }
足够聪明的博得先生!
//        S(a,b)={ (x,y)| x+y=a+b 且 1<x<y }
足够聪明的博得先生!

足够聪明的博得先生!#include 
<iostream>
足够聪明的博得先生!#include 
<cmath>
足够聪明的博得先生!
足够聪明的博得先生!
using namespace std;
足够聪明的博得先生!
足够聪明的博得先生!
#define MAXN 302500
足够聪明的博得先生!
#define MAXM 550
足够聪明的博得先生!
足够聪明的博得先生!
bool prime[MAXN];
足够聪明的博得先生!
足够聪明的博得先生!
//素数表的生成
足够聪明的博得先生!
void inline get_prime()
}

    执行一下,输入两个数(2~550之间)比如输入2、100就可以知道在 2~100 之间,满足条件的有四组:(4,13)、(4,61)、(16,73)、( 64,73)。

    至此程序应该是对的了,但由于没有找到哪个Online Judge上有这题,所以并没有递交过。那就欢迎大家的指正了!!!

参考书目:《算法艺术与信息学竞赛》

相关文章:

  • 2021-12-27
  • 2022-12-23
  • 2022-12-23
  • 2022-01-07
  • 2021-09-25
  • 2022-12-23
  • 2021-08-29
  • 2021-07-09
猜你喜欢
  • 2021-10-13
  • 2021-07-07
  • 2021-11-01
  • 2022-01-15
  • 2021-07-16
  • 2021-06-19
  • 2022-01-03
相关资源
相似解决方案