zoukankan      html  css  js  c++  java
  • 【编程题目】输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数, 使其和等于 m ... ★

    第 21 题(数组)
    2010 年中兴面试题
    编程求解:
    输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,
    使其和等于 m ,要求将其中所有的可能组合列出来.

    我的思路:

    从小到大 依次拼凑 后面选的数字 必须比前面大 保证不重复
    如: n = 4 m = 8
    1 2 3 4 超过8 去掉最后一个数 导数第二个数加一
    1 2 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
    1 3 4 符合 输出 最后一个数等于 4 去掉最后一个数 导数第二个数加一
    1 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
    2 3 小于8
    2 3 4 超过8 去掉最后一个数 导数第二个数加一
    2 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
    ......

    代码:

    /*
    第 21 题(数组)
    2010 年中兴面试题
    编程求解:
    输入两个整数  n  和  m,从数列 1,2,3.......n  中  随意取几个数,
    使其和等于  m ,要求将其中所有的可能组合列出来.
    start time = 15:55
    end time = 17:03
    */
    
    #include <iostream>
    using namespace std;
    
    
    int FindCombine(int n, int m)
    {
        int method = 0; //一共有多少方法
        if(m <= 0)
        {
            return 0;
        }
        else
        {
            int record[100]; //存储组合当前的取值
            for(int i = 0; i < 100; i++)
            {
                record[i] = i + 1;
            }
            int num = 0; //组合中数字的个数
            int sum = 0; //组合中数字加起来的和
    
            while(sum < m)
            {
                sum += record[num];
                num++;
    
                if(sum == m)
                {
                    method++;
                    printf("组合%d:", method);
                    for(int i = 0; i < num; i++)
                    {
                        printf("%d ", record[i]);
                    }
                    printf("
    ");
    
                    if(num == 1)
                    {
                        return method;
                    }
                }
                if((sum >= m) || (sum < m && record[num - 1] == n && num >= 2)) //如果大小超过m 或者 最后一个数字大小等于n 更新record
                {
                    num--;
                    sum -= record[num];
                    num--;
                    sum -= record[num];
                    if(record[num] <= n)
                    {
                        record[num]++;
                        for(int i = 1; i <= n - record[num]; i++)
                        {
                            record[i + num] = record[num] + i;  
                        }
                    }
                }
                else if(sum < m && record[num - 1] == n && num == 1)
                {
                    return method;
                }
            }
        }
    }
    
    
    
    int main()
    {
        int w = FindCombine(50, 100);
        return 0;
    }

    惯例上网找别人的方法, 一看我就郁闷了, 居然可以用动态规划, 我的算法算是白学了, 到用的时候一点都想不起来。

    http://blog.sina.com.cn/s/blog_7571423b01016707.html 里有个详细的分析

    http://www.cnblogs.com/freewater/archive/2012/07/16/2593218.html 里有非常精简的代码

    vector<int> factors;
    void findFactor2(int sum,int n){
        if(sum<0||n<0)
            return ;
        if(sum==0){
            for(vector<int>::iterator iter=factors.begin();iter!=factors.end();++iter){
                cout<<*iter<<' ';
            }
            cout<<endl;
            return;
        }
    
        factors.push_back(n);//典型的01背包问题  
        findFactor2(sum-n,n-1);//放n,n-1个数填满sum-n 
        factors.pop_back();
        findFactor2(sum,n-1);//不放n,n-1个数填满sum   
    }
  • 相关阅读:
    Devops的衍生-腾讯优测
    如何评估软件测试的效率
    优测云服务平台如何破解兼容性测试操作难点
    测试工程师进阶面试题目大合集
    测试人员必看-做好自动化测试的7大技能
    史上最全软件开发|程序员必备的工具集
    腾讯优测优分享 | 高质量产品、高质量照片
    腾讯优测优分享 | 多媒体,多问题
    腾讯优测优分享 | 双卡双待-工程师难言的痛
    C#面向对象基础
  • 原文地址:https://www.cnblogs.com/dplearning/p/3893266.html
Copyright © 2011-2022 走看看