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


  • 相关阅读:
    emacs 编程入门 函数
    boost库介绍
    jquery css attr
    html 相对定位 绝对 定位 css + div
    我常用的grep
    我常用的tar
    C#皮肤的用法(皮肤资源+使用实例下载)
    C#资源文件操作示例 创建资源和读取资源
    黄聪:c#中高效的excel导入sqlserver的方法
    黄聪:Delphi 中的 XMLDocument 类详解(2) 记要
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/571851.html
Copyright © 2011-2022 走看看