zoukankan      html  css  js  c++  java
  • 一道微软公司的面试题目的算法实现

    题目:        已知两个数字为1~30之间的数字,甲知道两数之和,乙知道两数之积,甲问乙:“你知道是  哪两个数吗?”乙说:“不知道”。乙问甲:“你知道是哪两个数吗?”甲说:“也不知道”。于是,乙说:“那我知道了”,随后甲也说:“那我也知道了”,这两个数是什么?

    下边是最佳答案:

    1和4 或者1和7
    推理1:允许两数重复的情况下
    答案为x=1,y=4;甲知道和A=x+y=5,乙知道积B=x*y=4
    不允许两数重复的情况下有两种答案
    答案1:为x=1,y=6;甲知道和A=x+y=7,乙知道积B=x*y=6
    答案2:为x=1,y=8;甲知道和A=x+y=9,乙知道积B=x*y=8
    解:
    设这两个数为x,y.
    甲知道两数之和 A=x+y;
    乙知道两数之积 B=x*y;
    该题分两种情况 :
    允许重复, 有(1 <= x <= y <= 30);
    不允许重复,有(1 <= x < y <= 30);
    当不允许重复,即(1 <= x < y <= 30);
    1)由题设条件:乙不知道答案
    <=> B=x*y 解不唯一
    => B=x*y 为非质数
    又∵ x ≠ y
    ∴ B ≠ k*k (其中k∈N)
    结论(推论1):
    B=x*y 非质数且 B ≠ k*k (其中k∈N)
    即:B ∈(6,8,10,12,14,15,18,20...)
    证明过程略。
    2)由题设条件:甲不知道答案
    <=> A=x+y 解不唯一
    => A >= 5;
    分两种情况:
    A=5,A=6时x,y有双解
    A>=7 时x,y有三重及三重以上解
    假设 A=x+y=5
    则有双解
    x1=1,y1=4;
    x2=2,y2=3
    代入公式B=x*y:
    B1=x1*y1=1*4=4;(不满足推论1,舍去)
    B2=x2*y2=2*3=6;
    得到唯一解x=2,y=3即甲知道答案。
    与题设条件:"甲不知道答案"相矛盾 ,
    故假设不成立,A=x+y≠5
    假设 A=x+y=6
    则有双解。
    x1=1,y1=5;
    x2=2,y2=4
    代入公式B=x*y:
    B1=x1*y1=1*5=5;(不满足推论1,舍去)
    B2=x2*y2=2*4=8;
    得到唯一解x=2,y=4
    即甲知道答案
    与题设条件:"甲不知道答案"相矛盾
    故假设不成立,A=x+y≠6
    当A>=7时
    ∵ x,y的解至少存在两种满足推论1的解
    B1=x1*y1=2*(A-2)
    B2=x2*y2=3*(A-3)
    ∴ 符合条件
    结论(推论2):A >= 7
    3)由题设条件:乙说"那我知道了"
    =>乙通过已知条件B=x*y及推论(1)(2)可以得出唯一解
    即:
    A=x+y, A >= 7
    B=x*y, B ∈(6,8,10,12,14,15,16,18,20...)
    1 <= x < y <= 30
    x,y存在唯一解
    当 B=6 时:有两组解
    x1=1,y1=6
    x2=2,y2=3 (∵ x2+y2=2+3=5 < 7∴不合题意,舍去)
    得到唯一解 x=1,y=6
    当 B=8 时:有两组解
    x1=1,y1=8
    x2=2,y2=4 (∵ x2+y2=2+4=6 < 7∴不合题意,舍去)
    得到唯一解 x=1,y=8
    当 B>8 时:容易证明均为多重解
    结论:
    当B=6时有唯一解 x=1,y=6当B=8时有唯一解 x=1,y=8
    4)由题设条件:甲说"那我也知道了"
    => 甲通过已知条件A=x+y及推论(3)可以得出唯一解
    综上所述,原题所求有两组解:
    x1=1,y1=6
    x2=1,y2=8
    当x<=y时,有(1 <= x <= y <= 30);
    同理可得唯一解 x=1,y=4


    推理2:只有1和7
    分析
    因为乙先说知道,说明乙通过这个乘积可以确定一组唯一的数,而甲后说知道了,说明甲通过乙提供的信息及两数之和也能确定唯一的一组数

    先看乘积

    如果是1和4,则乘积为4,可分解为1*4,2*2,不是唯一的一组
    如果是1和7,则乘积为7是质数,可以分解为1*7,是唯一的一组
    如果是4和7,则乘积为28,可分解为,4*7,2*14,1*28,不是唯一的一组
    如果是1和17,则乘积为17是质数,可分解为1*17,是唯一的一组
    如果是4和17,则乘积为68,可分解为2*34(不符合条件),和4*17,是唯一的一组
    如果是7和14,则乘积为98,可分解为49*2(不符合条件),和7*14,是唯一的一组

    由此筛选出1和7,1和17,4和17,7和14

    在看两数之和

    如果是1和7,则和为8,可分解为,1+7,2+6,3+5,4+4
    1、如果分解为2+6,则乘积为12,不能确定唯一的一组数相乘
    2、如果分解为3+5,则乘积为15,不能确定唯一的一组数相乘
    3、如果分解为4+4,则乘积为16,不能确定唯一的一组数相乘
    4、如果分解为1+7,则乘积为7,能确定唯一的一组数相乘
    因此1和7成立

    如果是1和17,则和为18,可分解为1+17,2+16,3+15....9+9
    其中,如果分解为1+17,则乘积为17,能确定唯一的一组数相乘
    如果分解为5+13,则乘积为65,能确定唯一的一组数相乘
    这样至少有两组解符合条件
    因此1和17不成立

    如果是4和17,则和为21
    其中
    如果分解为2+19,则乘积为38,能确定唯一的一组数相乘
    如果分解为4+17,则乘积为68,能确定唯一的一组数相乘
    这样至少有两组解符合条件
    因此4和17不成立

    如果是7和14,则和为21
    其中
    如果分解为2+19,则乘积为38,能确定唯一的一组数相乘
    如果分解为4+17,则乘积为68,能确定唯一的一组数相乘
    这样至少有两组解符合条件
    因此4和17不成立

    总上,只有1和7符合条件


    推理3:由乙开始推理:2*2=4或1*4=4 假设是2和2的话,甲所得的数是4,那么甲就会想“2+2=4, 1+3=4,那么他(乙)就会认为我所的数是3或4,如果是3的话,那么我(甲)就知道结果 1*3=3,现在他(乙)不知道,那么只能是2*2=4,相信他(乙)现在也得出了这个结果。可是他(乙)还要反问我(甲)知不知道,那么就是说2*2=4这个结果不成立,那么只能是1*4=4






    以下用VB。NET实现:


        Dim NUM, SUM, PRODUCT As Int32
        Dim Product1()() As Int32
        Dim i, m, n, Sum1(3)() As Int32


        Private Sub MyMain()
            Product1 = Nothing
            NUM = CInt(Me.TextBox1.Text)
            GetSum1()
            GetProduct1()
            For m = 1 To NUM
                For n = m To NUM
                    If SumOnly(m, n) Or ProductOnly(m, n) Then GoTo NextItem '不好意思用了个GOTO
                    SUM = m + n
                    PRODUCT = m * n
                    '甲的和产生的积中最多有(n -2)个是唯一积
                    If SUMtoPRODUCT_N_2(SUM) < 2 Then GoTo NextItem
                    '乙的积产生的和中有且只有一个满足1、不是唯一和 2、和产生的积中最多有(n -2)个是唯一积
                    '并且其余的和均满足 1、不是唯一和 2、有n-1个唯一积
                    If PROCUCTtoSUM(PRODUCT) Then
                        MsgBox(m.ToString() & "  " & n.ToString())
                    End If
    NextItem:   Next


            Next


        End Sub
        Private Sub GetSum1()
            '产生唯一和并保存在数组中
            ReDim Sum1(0)(1)
            Sum1(0)(0) = 1
            Sum1(0)(1) = 1
            ReDim Sum1(1)(1)
            Sum1(1)(0) = 1
            Sum1(1)(1) = 2
            ReDim Sum1(2)(1)
            Sum1(2)(0) = NUM - 1
            Sum1(2)(1) = NUM
            ReDim Sum1(3)(1)
            Sum1(3)(0) = NUM
            Sum1(3)(1) = NUM
        End Sub
        Private Function SumOnly(ByVal N1 As Int32, ByVal N2 As Int32) As Boolean
            '判断是否为唯一和
            Dim i As Int32
            For i = 0 To 3
                If N1 = Sum1(i)(0) AndAlso N2 = Sum1(i)(1) Then Return True
            Next
            Return False
        End Function
        Private Sub GetProduct1()
            '产生唯一积并保存在数组中
            Dim tmp(NUM * NUM)() As Int32
            For m = 1 To NUM '????????????????
                For n = m To NUM  '??????????????
                    Dim meme() As Int32 = tmp(m * n)
                    If meme Is Nothing Then
                        ReDim meme(2)
                    Else
                        ReDim Preserve meme(meme.Length + 1)
                    End If


                    meme(meme.Length - 1) = m
                    meme(meme.Length - 2) = n
                    meme(0) += 1
                    tmp(m * n) = meme
                    meme = Nothing
                Next
            Next
            For i = 1 To NUM * NUM
                If Not tmp(i) Is Nothing AndAlso tmp(i)(0) = 1 Then
                    For m = 1 To tmp(i).GetUpperBound(0) Step 2
                        If Product1 Is Nothing Then
                            ReDim Product1(0)
                            ReDim Product1(0)(1)
                        Else
                            ReDim Preserve Product1(Product1.Length)
                            ReDim Product1(Product1.Length - 1)(1)
                        End If
                        Product1(Product1.Length - 1)(0) = tmp(i)(m)
                        Product1(Product1.Length - 1)(1) = tmp(i)(m + 1)
                    Next
                End If
            Next
        End Sub
        Private Function ProductOnly(ByVal N1 As Int32, ByVal N2 As Int32) As Boolean
            '判断是否为唯一积
            Dim i As Int32
            For i = 0 To Product1.GetUpperBound(0)
                If N1 = Product1(i)(1) AndAlso N2 = Product1(i)(0) Then Return True
                If N1 = Product1(i)(0) AndAlso N2 = Product1(i)(1) Then Return True
            Next
            Return False
        End Function
        Private Function SUMtoPRODUCT_N_2(ByVal SUM As Int32) As Int32
            '甲的和产生的积中最多有(n -2)个是唯一积
            Dim n As Int32 = CInt(SUM / 2 - 0.2)
            Dim i, m As Int32
            For i = 1 To n
                If ProductOnly(i, SUM - i) Then m += 1
            Next
            Return n - m
        End Function
        Private Function PROCUCTtoSUM(ByVal PRODUCT As Int32) As Boolean
            '乙的积产生的和中有且只有一个满足1、不是唯一和 2、和产生的积中最多有(n -2)个是唯一积
            '并且其余的和均满足 1、不是唯一和 2、有n-1个唯一积
            Dim tmp()(), i, m, n As Int32
            '1、分解积看能产生多少个和
            For i = 1 To CInt(Math.Sqrt(PRODUCT) - 0.4)
                If PRODUCT Mod i = 0 Then
                    If tmp Is Nothing Then
                        ReDim tmp(0)
                        ReDim tmp(0)(2)
                    Else
                        ReDim Preserve tmp(tmp.Length)
                        ReDim Preserve tmp(tmp.Length - 1)(2)
                    End If
                    tmp(tmp.Length - 1)(2) = PRODUCT / i
                    tmp(tmp.Length - 1)(1) = i
                    If Not SumOnly(tmp(tmp.Length - 1)(1), tmp(tmp.Length - 1)(2)) And SUMtoPRODUCT_N_2(i + PRODUCT / i) >= 2 Then
                        '和不为唯一和,且和产生的积中支多有n-2个是唯一积
                        tmp(tmp.Length - 1)(0) = 1
                    End If
                    If SumOnly(tmp(tmp.Length - 1)(1), tmp(tmp.Length - 1)(2)) Then
                        '唯一和
                        tmp(tmp.Length - 1)(0) = 3
                    End If
                    If Not SumOnly(tmp(tmp.Length - 1)(1), tmp(tmp.Length - 1)(2)) And SUMtoPRODUCT_N_2(i + PRODUCT / i) = 1 Then
                        '不是唯一和,但是有n-1个唯一积
                        tmp(tmp.Length - 1)(0) = 2
                    End If
                End If
            Next
            Dim count As Int32 = 0
            For i = 0 To tmp.Length - 1
                If tmp(i)(0) = 0 Then Return False
                If tmp(i)(0) = 1 Then count += 1
            Next
            If count <> 1 Then Return False
            Return True
        End Function


  • 相关阅读:
    ActiveMQ 即时通讯服务 浅析
    Asp.net Mvc (Filter及其执行顺序)
    ActiveMQ基本介绍
    ActiveMQ持久化消息的三种方式
    Windows Azure Virtual Machine (27) 使用psping工具,测试Azure VM网络连通性
    Azure China (10) 使用Azure China SAS Token
    Windows Azure Affinity Groups (3) 修改虚拟网络地缘组(Affinity Group)的配置
    Windows Azure Storage (22) Azure Storage如何支持多级目录
    Windows Azure Virtual Machine (26) 使用高级存储(SSD)和DS系列VM
    Azure Redis Cache (2) 创建和使用Azure Redis Cache
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/571851.html
Copyright © 2011-2022 走看看