微软面试题之数字谜题方案

设有两个自然数m,n,2〈=m<=99。 S先生知道这两数的和s,P先生知道这两数的积p。他们两人进行了如下的对话:
S:我知道你不知道这两个数是什么,但我也不知道。
P:现在我知道这两个数了。
S:现在我也知道这两个数了。
由这些条件,试确定m,n。

因为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
在[2,99]内有唯一的整数解。

根据这个性质计算出的p有以下的情况(不妨设m<=n):

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<>n,则最后的解答就是
 m=4 , n=13

下面是程序:

#include <iostream.h>
#include <fstream.h>
#include <string.h>

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 primCounter =0;

ofstream fout( OUTPUT_FILE );

// 计算素数
void calPrim()
{
 bool used[MAX_N];
 int i, p=2;
 bool found = true;
 
 prim[primCounter++] = 2;
 memset( used, false, sizeof( used ) );
 
 while( found ) {
  for( i = p; i < MAX_N; i++ )
   if( i % p == 0 )
    used[i] = true;

found = false;

for( i = p; i < MAX_N; i++ )
   if( ! used[i] ) {
    p = i;
    prim[primCounter++] = p;
    found = true;
    break;
   }
 }
}

// 根据条件1过滤
void useCon_1()
{
 int i,j;
 memset(s, 0, sizeof(s)); 
 
 for( i = 0; i < 4; i++ ) s[i] =-1;

calPrim();

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

for( i = 0; i < primCounter; i++ )
  for( j = i; j < primCounter; j++ ) {
   if( prim[i] + prim[j] < MAX_N * 2 )
    s[ prim[i] + prim[j] ] = -1;
  }

for( i = 0; i < primCounter; i++ )
  if( prim[i] > MAX_N / 2 ) break;

for( i--; i < primCounter; i++ )
  for( j = 2; j < MAX_N; j++ )
   s[ prim[i] + j ] = -1;

// 因为S自己也不知道这两个数是什么
 for( i = 98 + 99; i < MAX_N + MAX_N; i++ )
  s[i] = -1;

fout << "满足S第一句话的两数之和" << endl;
 for( i = 0; i < MAX_N * 2; i++ )
  if( s[i] == 0 )
   fout << i << endl;
}

// 根据条件2过滤
void useCon_2()
{
 int i, m, n;
 memset( p, 0, sizeof( p ) );

for( m = 2; m < MAX_N; m++ )
  for( n = 2; n < MAX_N; n++ ) {
   if( s[m+n] >= 0 ) {
    p[m*n]++;
   }
  }

fout << "满足P第一句话的两数之积:" << endl;

for( i = 0; i < MAX_N * MAX_N; i++ )
  if( p[i] == 1 || p[i] == 2 ) {
   for( m = 2; m < MAX_N; m++ )
    for( n = m; n < MAX_N; n++ )
     if( m * n == i && s[m + n] >= 0 ) {
      fout << "p = " << i
       << ", s= " << m + n
       << ", m = " << m
       << ", n = " << n << endl;
      s[m+n]++;
     }   
  }
 
}

void useCon_3()
{
 int i, m, n;
 fout << "满足S第二句话的结果:" << endl;
 
 for( i = 0; i < MAX_N * MAX_N; i++ )
  if( p[i] == 1 || p[i] == 2 ) {
   for( m = 2; m < MAX_N; m++ )
    for( n = m; n < MAX_N; n++ )
     if( m * n == i && s[m + n] == 1 ) {
      fout << "p = " << i
       << ", s = " << m + n
       << ", m = " << m
       << ", n = " << n << endl;
     }   
  }
}

void main()

 useCon_1();
 useCon_2();
 useCon_3(); 
}

微软面试题之数字谜题方案相关推荐

  1. 微软面试题之数字谜题 (转)

    微软面试题之数字谜题 (转)[@more@] 设有两个自然数m,n,2〈=m<=99. S先生知道这两数的和s,P先生知道这两数的积p.他们两人进行了如下的对话: S:我知道你不知道这两个数是什 ...

  2. 微软面试题之数字谜题

    设有两个自然数m,n,2〈=m<=99. S先生知道这两数的和s,P先生知道这两数的积p.他们两人进行了如下的对话: S:我知道你不知道这两个数是什么,但我也不知道. P:现在我知道这两个数了. ...

  3. 微软面试题:3,3,8,8,四个数字任意加减乘除使之最后等于24的编程解决方法

    微软面试题:3,3,8,8,四个数字任意加减乘除使之最后等于24的公式 四个数字,四中操作方式,括号的取舍.. 空间复杂度:4!*A(4,3)*C(8) = 12288次,差不多就计算完了. 用jav ...

  4. 微软面试题:有100万个数字(1到9),其中只有1个数字重复2次,如何快速找出该数字

    /******************************************************************************* 文 件 名 : test100.cpp ...

  5. c语言穷举法等式求缺位数,四年级下册数学奥数试题-培优拓展训练--第13讲:数字谜题(教师版)...

    第十三讲数字谜题 ------------------------------------------------------------------------------------------- ...

  6. 变态而有趣的微软面试题及答案

    变态而有趣的微软面试题及答案 变态而有趣的微软面试题及答案 文章目录 变态而有趣的微软面试题及答案 第一组 第二组 第三组 第四组 第五组 第六组 答案 最近和一些朋友讨论面试题比较多,呵呵,这里收藏 ...

  7. 算法--微软面试:指定数字在数组中出现的次数

    Q题目 在排序数组中,找出给定数字的出现次数,比如 [1, 2, 2, 2, 3] 中2的出现次数是3次. Answer解法 这道题要求出结果不难,但要求最有解的话,就需要花费一番功夫了.常见解法有如 ...

  8. 微软面试题--10个问题的逻辑推理题

    非常有趣的微软面试题: /* 请回答下面10个问题: 1.第一个答案是b的问题是哪一个? (a)2:(b) 3:(c)4:(d)5:(e)6 2.唯一的连续两个具有相同答案的问题是: (a)2,3:( ...

  9. 每日微软面试题——day 3

    <以下微软面试题全来自网络> <以下答案与分析纯属个人观点,不足之处,还望不吝指出^_^> 题:怎样从顶部开始逐层打印二叉树结点数据?请编程. 分析:不用递归,定义两个栈(或数 ...

最新文章

  1. linux 检测添加磁盘空间,Linux构造磁盘空间满的测试环境
  2. [Ms SQL] 基本創建、修改與刪除
  3. 在AWS S3的连接过程中发生java.lang.BootstrapMethodError: call site initialization exception
  4. Java开发中模拟接口工具moco的使用
  5. python后台架构Django教程——数据模型Model
  6. 【转】No Persistence provider for EntityManager问题
  7. 解决方案: NIS+NFS+AUTOFS
  8. SolrJ 查询数据
  9. 计算机odbc数据源管理位置,ODBC 常见数据源配置整理
  10. onlyoffice添加中文字体及字号
  11. erstudio连接mysql_ERStudio的使用
  12. raw文件格式 Android,手机摄影知识讲堂:关于RAW格式的那些事
  13. 一种考虑时空关联的深度学习短时交通流预测方法
  14. 企业地图定位,其实这是免费的!
  15. echarts柱形图x轴y轴互换_echarts图表x,y轴的设置
  16. JAVA一维数组求和
  17. 子集构造法NFA转换成DFA
  18. 《中国民生银行天眼日志平台架构演进的平凡之路》阅读有感
  19. 简析无线网络加密算法之CCMP加密算法
  20. c语言计算日出日落时间_日出日落时间 计算软件 日出日落时间计算公式

热门文章

  1. 数据分析师出品:新媒体运营年终总结模板分享
  2. 把一个字符串13579先变成Array——[1, 3, 5, 7, 9],再利用reduce(),就可以写出一个把字符串转换为Number的函数。
  3. android 插屏广告代码,插屏(Interstitial)广告样式
  4. switch基础用法
  5. 中国大陆程序员2020年工资城市分布图
  6. 姓名拆分为姓氏和名字的方法
  7. yocto 下载代理
  8. 弘辽科技:不拼低价,95后小伙3个月从0冲上150万
  9. HTML figcaption 标签
  10. 系统问题导致的笔记本部分按键失灵