【編程題目】輸入兩個整數 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("\n");

                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   
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找 Problem Description 有一個長度為n(n<=100)的數列,該數列定義為從2開始的遞增有序偶數,現在要求你按照順序每m個數求出一個平均值,如果最后不足m個,則以實際數量求平均值。編程輸出該平均值序列。 Input 輸入數據有多組,每組占一行,包含兩個正整數n和m,n和m的含義 Problem Description 有n(n<=100)個整數,已經按照從小到大順序排列好,現在另外給一個整數x,請將該數插入到序列中,並使新的序列仍然有序。 Input 輸入數據包含多個測試實例,每組數據由兩行組成,第一行是n和m,第二行是已經有序的n個數的數列。n和m同時為0標示輸入數 階乘因式分解(一) 給定兩個數m,n,其中m是一個素數。 將n(0<=n<=10000)的階乘分解質因數,求其中有多少個m。 輸入第一行是一個整數s(0 【JAVA習題六】輸入兩個正整數m和n,求其最大公約數 輸入正整數m和n,m 有n個整數,使其前面各數順序向后移n-m個位置,最后m個數變成最前面的m個數 從鍵盤輸入一個字符串,再輸入兩個正整數m和n,輸出字符串中從m開始,連續n個字符。例如,輸入abcdefg,2,3,輸出bcd。 10.4 有n個整數,使前面各數順序向后移m個位置,最后m個數變成前面m個數,見圖。寫一函數:實現以上功能,在主函數中輸入n個數和輸出調整后的n個數。 有 n個整數,使其前面各數順序向后移 m 個位置,最后m個數變成最前面的 m 個數。 Problem C: 指針:有n個整數,使其前面各數順序向后移m個位置,最后m個數變成最前面m個數
 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM