查看完整版本: 考題檢討
頁: [1]

zz2242zz 發表於 2016-11-11 11:32 AM

考題檢討

昨天考試我有兩題不會做了,題目老師禁止外流,我大致上只記住其中一題。

輸入兩個整數M和N,分別代表數列的第幾項(2+4+8+16+......這數列),顯示M到N向的和。

範例:
輸入兩個正整數:5 10
32+64+128+256+512+1024=2016

-------------------------------------
總和我考試後才想到(忘記會多減一個數),但我不知道要怎麼顯示M到N中間的數。
這是我目前的程式碼:
        cout<<"輸入兩個正整數:" ;
        cin>>M>>N ;
        a=1 ;
        for(i=1;i<=M;i++)
        {
                a*=2 ;
        }
        b=1 ;
        for(i=1;i<=N;i++)
        {
                b*=2 ;
        }
        cout<<a<<"+......+"<<b<<"="<<(2.0)*(b-a/2)  ;
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

scottcheng 發表於 2016-11-11 12:43 PM

一個迴圈可以解決 e.g.  for (i=m;i<=n;i++) {}
2次方可以用   1 << i ;   e.g.  1<<5 =32   1<<10 = 1024
在迴圈可以判斷  先印 1 << i  , 再判斷 if (i==n) cout << "="; else cout << "+"
最後在印sum

這樣的提示, 希望你自己可以想出怎麼寫! 或是有更好的寫法

baepi 發表於 2016-11-11 03:30 PM

既然都考完了~那我怎麼說應該都不算作弊了吧...
其實這題蠻有意思的...要讓您求M的值很容易~N的值也如此...但是這題感覺是考程式的流程
首先輸入兩個數M和N....但是沒說誰大誰小...甚至輸入負數怎麼辦?嘿嘿...我寫的也沒考慮負數...因為又不是我在考試^^
所以首先應該是要先確認誰大誰小...知道後~方法就有百百種~最開始我想的是類似於跑馬燈的方式
類似於如下int a;
for( int i = 0 ; i < 32 ; i++ )
{
  if( i == 0 )
  {
     a = 1 ;
  }
  else
  {
     a *= 2 ;
  }
....後面開始下判斷式
}這樣的好處是在這for迴圈內就可以搞定...但是看完大大的想法~我就配合大大的思路走
如下...#include <iostream>
using namespace std;

void main()
{
        int m , n ;
        cout << "請先輸入兩個數值\n第一個數 : " ;
        cin >> m ;
        cout << "第二個數 : " ;
        cin >> n ;

        if( m < n )
        {
                int buf = m ;
                m = n ;
                n = buf ;
        }        //如此轉換完後可以保證 m 的值大於等於 n

        int a = 1 ;

        for( int i = 0 ; i < n ; i++ )        //這裡的i並無實質作用~只是為了讓迴圈可以做 N 次
        {
                a *= 2 ;
        }

        int sum = a ;

        cout << "算式為 : " ;
        cout << a ;

        for( int i = n ; i < m ; i++ )
        {
                cout << " + ";
                a *= 2 ;
                sum += a;
                cout << a ;
        }
        cout << " = " ;
        cout << sum << endl ;
}是不看完覺得一點也不難呢{:31:}...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

scottcheng 發表於 2016-11-11 06:28 PM

樓上參考看看吧. 程式依邏輯一步一步走, 可能會程式很長, 寫習慣後, 有時候可以用很簡單的寫法就可以達到目的#include <iostream>
using namespace std;

int main(void)
{
  int s=0, i, c;
  int m,n;

  cin >> m >> n;

  for (i=m; i<=n; i++)
  {
    c = 1 << i;
    s = s + c;
    cout << c;
  
    if (i == n)
      cout << "=" << s << endl;
    else
      cout << "+";
  }
  return 0;
}

baepi 發表於 2016-11-11 09:24 PM

scottcheng 發表於 2016-11-11 06:28 PM static/image/common/back.gif
樓上參考看看吧. 程式依邏輯一步一步走, 可能會程式很長, 寫習慣後, 有時候可以用很簡單的寫法就可以達到目 ...

還是打一篇補充說明好了...
1.
左移右移本來就是一個快速但又容易讓人在需要時想起的法子...可能是因為他只適用於2基底運算
像是1 3 9 27 ...就沒辦法直接套用....我完全認同大大的說明~只是要說給可能沒在用的人一個觀念(就當我在對空氣說話)

2.
更主要的原因是...通常我留言前會先看是否有解答已經說明完整...感覺尚未完整就來騙個積分(誤)
所以通常點評魔人snowflying大大點評完後我都絕不留言~因為他已經把精要處都說完了~再說也只是畫蛇添足...所以既然大大已經提供左移了~我何必補充說明~直接用發問者的邏輯去延伸不是讓他更容易懂嗎?
更何況無論是用左移還是笨拙的迴圈乘法都可以...只是速度天差地遠~{:33:}
所以當初我在你後面補充解答只是因為看您沒說明這題目的小陷阱...m和n要先比大小~甚至您在4樓的解答也沒添加~若是使用者填入的值 m < n 呢?
以上回復並無想要冒犯大大專業之心~只是講述為何在2樓看您回復後依舊不用左移之因~以及您疏漏 m 與 n 的大小比較...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

scottcheng 發表於 2016-11-12 05:55 PM

本帖最後由 scottcheng 於 2016-11-12 05:58 PM 編輯

大小並不是重點, 重點在於邏輯設計. 我當初只留言就是為了讓樓主自己思考一下. 反正妳都寫code了, 我就順便提供另外一種寫法給樓主參考. 程式設計本來就是多討論, 相互進步. 不用擔心冒犯, 如有錯誤, 本應該提醒指教. 如果有更好寫法, 也可以指教.

zz2242zz 發表於 2016-11-13 08:57 PM

感謝樓上兩位的解惑,抱歉我沒及時看到(沒登出好像就收不到別人回復的消息)。

老實說我昨晚又多想了下,是有考慮到迴圈內含另外的迴圈。

教我們班計算機程式的老師是老媽子個性,我認為有極高的機率不會教超出範圍的題目。
在幾次失敗後,我寫出大概是老師要的程式碼了:


        //第四小題
        cout<<"輸入兩個正整數:" ;
        cin>>M>>N ;
        a=1 ;
        b=1 ;
        for(i=1;i<=M;i++)
        {
                a*=2 ;
        }
        e=a ;
        for(i=1;i<=N;i++)
    {
            b*=2 ;
        }
       
        cout<<a ;
        for(i=M+1 ; i<N ; i++)
        {
                e*=2 ;
                cout<<'+'<<e ;
        }
        cout<<'+'<<b<<"="<<(2.0)*(b-a/2)  ;
        cout<<endl ;
        system("pause") ;
        return 0 ;

可惜我考試時傳上去是這樣{:54:}:

        //第四小題
        cout<<"輸入兩個正整數:" ;
        cin>>M>>N ;
        a=1 ;
        for(i=1;i<=M;i++)
        {
                a*=2 ;
        }
        b=1 ;
        for(i=1;i<=N;i++)
        {
                b*=2 ;
        }
        cout<<a<<"+......+"<<b<<"="<<(M-N+1)*(b-1)/(2-1)  ;
        cout<<endl ;
        return 0 ;

當時太緊張,連system都拼錯(不小心多打一個r),為了能順利跑程式我只好刪掉{:38:}。

在此感謝前輩們的指導。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

inunu 發表於 2016-11-14 03:38 AM

可以不用 for 嗎?    int m, n;
    cin >> m >> n;
    cout << (1 << (n + 1)) - (1 << m) << endl;

inunu 發表於 2016-11-14 09:00 AM

中間每個數都要顯示出來就只能用迴圈了

第三行是外星人早上剛跟我講的解答
頁: [1]