#1 - 2009-8-8 20:09
(请叫我预言帝)

题记:今天刚好看到群里有人问,平时一向比较不是很喜欢这种脑残智力题的(喂),不过今天还是用程序写了个……没找到标准答案,所以有可能有错,随便了= =||


已知:x和y都是自然数,且1<x<y<30.
我把x+y的结果告诉了甲,把x*y的结果告诉了乙。
甲说:“我不知道x和y各是多少。”
乙说:“我也不知道x和y各是多少。”
甲又说:“我知道x和y是多少了。”
接着乙也说:“我也知道x和y是多少了”。
请问:x和y各是多少。

代码如下:

    #include "stdafx.h"

    // ============================================================================
    // ==============================================================================

    int SumNum(int nSum)
    {
        //~~~~~~~~~
        int nX = 0;
        int nY = 0;
        int nCnt = 0;
        //~~~~~~~~~

        for (nX = 2; nX < 30; ++nX) {
            for (nY = nX + 1; nY < 30; ++nY) {
                if (nX + nY == nSum) {
                    ++nCnt;
                }
            }
        }

        return nCnt;
    }

    // ============================================================================
    // ==============================================================================
    int ProductNum(int nProduct)
    {
        //~~~~~~~~~
        int nX = 0;
        int nY = 0;
        int nCnt = 0;
        //~~~~~~~~~

        for (nX = 2; nX < 30; ++nX) {
            for (nY = nX + 1; nY < 30; ++nY) {
                if (nX * nY == nProduct) {
                    ++nCnt;
                }
            }
        }

        return nCnt;
    }

    // ============================================================================
    // ==============================================================================
    int OneSumProductNotOnlyOneNum(int nSum)
    {
        //~~~~~~~~~
        int nX = 0;
        int nY = 0;
        int nCnt = 0;
        //~~~~~~~~~

        for (nX = 2; nX < 30; ++nX) {
            for (nY = nX + 1; nY < 30; ++nY) {
                if (nX + nY == nSum && ProductNum(nX * nY) > 1) {
                    ++nCnt;
                }
            }
        }

        return nCnt;
    }

    // ============================================================================
    // ==============================================================================
    bool HaveXY(int nSum, int nProduct, int &nX, int &nY)
    {
        //~~~~~~~~~
        int nCnt = 0;
        //~~~~~~~~~

        for (nX = 2; nX < 30; ++nX) {
            for (nY = nX + 1; nY < 30; ++nY) {
                if (nX + nY == nSum && nX * nY == nProduct) {
                    return true;
                }
            }
        }

        return false;
    }

    // ============================================================================
    // ==============================================================================
    int _tmain(int argc, _TCHAR *argv[])
    {
        //~~~~~~~~~~~~~~
        int nSum = 0;
        int nProduct = 0;
        int nX = 0;
        int nY = 0;
        int nCnt = 0;
        int nSumStore = 0;
        //~~~~~~~~~~~~~~

        for (nProduct = 4; nProduct < 900; ++nProduct) {
            nCnt = 0;
            for (nSum = 4; nSum < 60; ++nSum) {
                if (HaveXY(nSum, nProduct, nX, nY) && SumNum(nSum) > 1
                && ProductNum(nProduct) > 1) {
                    if (nSum == 17) {
                        int t = 1;
                    }
                    if (OneSumProductNotOnlyOneNum(nSum) == 1) {
                        nSumStore = nSum;
                        ++nCnt;
                    }
                }
            }

            if (nCnt >= 1) {
                HaveXY(nSumStore, nProduct, nX, nY);    // Get X, Y here
                printf("Sum %d Product %d x %d y %d\n", nSumStore, nProduct, nX, nY);
            }
        }

        getchar();
        return 0;
    }



结果:

Sum 8 Product 12 x 2 y 6
Sum 10 Product 24 x 4 y 6
Sum 42 Product 432 x 18 y 24
Sum 46 Product 504 x 18 y 28


咱还以为是一组解呢,原来有四组么……顺便……甲乙你们只是聪明而已?确定不是人形自走电脑么= =||



P.S. 解的解释


e.g.

x=18/y=24/和42 乘积 432
13 29 30内唯一分解
14 28 30内唯一分解
15 27 30内唯一分解
16 26 30内唯一分解
17 25 30内唯一分解
18 24 还有 16 27的分解
19 23 30内唯一分解
20 22 30内唯一分解

这样就可以确定,一定是18/24
这组解同时也满足,乙知道甲知道后也知道的情况,乘积在432时,只有42满足上述条件,所以乙也能知道
#2 - 2009-8-9 00:18
我知道了lz您用的是visual studio写的代码...
#3 - 2009-8-9 02:00
(第00自宅警备员小队)

是C么. 看到花括号才与Basic区别开来= =
#4 - 2009-10-6 01:42
(greetings from the ocean)
1.竟然是C
2.竟然真的有人用C解决问题
=> 技术宅真可怕
呼唤Java和MATLAB
#5 - 2009-10-6 08:52
(唉唉唉唉)
学过2个月C纯粹为计算机考级而学的发来贺电并表示

技术宅真可怕
#6 - 2009-10-7 22:52
(煩到想殺人~~~)
能看C的路過~~就是不會寫~
#7 - 2009-10-10 20:54
(越来越懒=。=)
总感觉有些问题,以第一组答案为例:

如果甲知道xy的和为8,则可能是x2y6或x3y5;若是x3y5,则积15,只有一种分解,因此结果必是x2y6;
但是当xy的和为7,可能为x2y5或x3y4;若是x2y5,则积为10,只有一种分解,因此结果必是x3y4;
但是此时对于乙,只知道积为12,就无法确定和是7或8,因此,乙不可能得出答案啊=。=
#8 - 2009-10-13 00:57
据我分析(x+y,x*y)可取的序列有(7,12),(12,20),(14,24),(16,28),(13,30),(17,30)
问题的关键在于乙一开始不知道,说明x*y的值有大于等于5个公约数(即除去1和本身至少还有三个公约数),符合的x*y的值有12,16,18,20,24,28,30
然后每种情况反推出x+y的值,在不同的x*y条件下,若得到同一x+y值,则不符合条件,如x+y=12,则x*y为7或8,而x+y=16时也有x*y为8或10,故8是不符合条件的,一定要舍去,最后便得到上述分析结果~
#9 - 2009-10-13 07:19
呃 好像还是有些问题 至少 (13,30),(17,30)也要舍去!!!!!!!!!!
#10 - 2009-10-15 23:02
(Happy Coding)
宅技术真可怕
#11 - 2009-10-16 22:16
(秋菜)
技术宅真可怕~~