c語言 解釋程式流程

題目是

a + 2b + 3c + 4d + 5e + 6f >= 10

2a + 3b + 4c + 5d + 6e + 7f <= 21

求所有解(a~f皆為正整數)

請哪位高手可以幫忙解釋一下程式的流程

幫忙註解一下

#include <iostream>

int main()

{

const int min_rate[]= {1,2,3,4,5,6};

const int max_rate[]= {2,3,4,5,6,7};

const int var_size=sizeof(min_rate)/sizeof(int);

int var[var_size]= {0};

int min=10,max=21;

int sum_min=0,sum_max=0;

while(sum_max<=max)

{

for(var[0]=0; sum_max<=max; ++var[0])

{

if(sum_min>=min)

{

for(int i=0; i<var_size; ++i)

std::cout << var[i] << ' ';

std::cout << std::endl;

}

sum_max+=max_rate[0];

sum_min+=min_rate[0];

}

for(size_t i=0; sum_max>max && i<var_size-1 ; ++i)

{

sum_max-=var[i]*max_rate[i]-max_rate[i+1];

sum_min-=var[i]*min_rate[i]-min_rate[i+1];

var[i]=0;

++var[i+1];

}

}

}

2 個解答

評分
  • 10 年前
    最佳解答

    這個程式的某些流程,原創者已予以人工優化過了,若能把它還原得「白話」一點,將有助於理解。

    這個程式具規律性,若不考慮執行效率,似可改以遞迴來呈現。

    程式的邏輯可再改善一些。(提示:周而復始,未必得歸零。)

    由於直覺這個程式還有改善空間,所以我不會去評析它。

    解鈴還待繫鈴人,建議提問者何不直接去問原創者,豈不更直接了當!

    2011-05-26 14:35:31 補充:

    原創者既不可尋,那改個手法吧!

    我不喜歡對非自己作品加註解,但我可用另外的方式幫你去領悟它。

    在不改變原程式邏輯的前提下,約略修改其呈現方式。

    改寫後,程式的流程是否已較清晰了?

    再用點心去思考它,應不難看出其程式邏輯的來龍去脈。

    幾分鐘後,或幾小時後,或數日後,

    你將會發現,烘烤自己釣的魚,吃起來特別甘甜。

    #include <iostream>

    #define increase(i) \

    {sum_max+=max_rate[i]; sum_min+=min_rate[i]; ++var[i];}

    #define zero(i) \

    {sum_max-=var[i]*max_rate[i];sum_min-=var[i]*min_rate[i];var[i]=0;}

    #define printSolution {\

    std::cout << ++count << ": "; \

    for(int i=0; i<var_size; ++i) \

    std::cout << var[i] << ' '; \

    std::cout << std::endl;}

    int main()

    {

    const int min_rate[]= {1,2,3,4,5,6};

    const int max_rate[]= {2,3,4,5,6,7};

    const int var_size=sizeof(min_rate)/sizeof(int);

    int var[var_size]= {0};

    int min=10, max=21, count=0;

    int sum_min=0, sum_max=0;

    while (sum_max <= max)

    {

    for (var[0]=0; sum_max <= max; /* ++var[0] */)

    {

    if (sum_min >= min)

    {

    printSolution ;

    }

    increase(0);

    //sum_max+=max_rate[0];

    //sum_min+=min_rate[0];

    }

    for(size_t i=0; sum_max > max && i < var_size-1 ; ++i)

    {

    zero(i);

    increase(i+1);

    //sum_max-=var[i]*max_rate[i]-max_rate[i+1];

    //sum_min-=var[i]*min_rate[i]-min_rate[i+1];

    //var[i]=0;

    //++var[i+1];

    }

    }

    system("pause");

    }

    2011-05-26 18:52:03 補充:

    >>for(size_t i=0; sum_max > max && i < var_size-1 ; ++i)

    若加權上界(sum_max)越界,

    則由第一個變數開始逐一歸零,並遞增次一變數,

    直到上界未越界或已遞增到最後一個變數了。

    這個迴圈結束後的 sum_max ,

    便作為主控迴圈判斷是否該繼續的依據。

    2011-05-26 19:04:36 補充:

    至於sum_max的計算是用「差額累計法」來運作的。

    舉個日常生活的例子,

    你去超市買啤酒,買了若干缶,已計好總額了,

    此時要加購一缶,只要加這缶的差額即可,

    此即 increase(某一變數) 的做法。

    至於歸零的動作,也是類似的,

    退還N缶,只要從總額扣減N缶的錢即可。

    此即 zero(某一變數) 的做法。

  • 10 年前

    此程式碼在論壇上得到的

    我在三月份有記過提問信給原創

    至今都無訊息= =

    2011-05-26 17:11:38 補充:

    謝謝東邪大大

    這樣的流程就易懂ㄌ

    是否是先運算完後

    再歸0?

    我還是有點不懂後面的

    for(size_t i=0; sum_max > max && i < var_size-1 ; ++i)

    是甚麼意思= =

還有問題?馬上發問,尋求解答。