2016年6月11日 星期六

台中女中b005

b005:熱門點播
方法一:不可行?
讀入n個數字,假設10個數字,且讀入的數字< MaxN(1000000)的話,
可以類似b002直接宣告陣列且在1~MaxN找出現最多的是哪一個
例如輸入: 10 55555 666 7777 99999 55555 333 22 111 55555 22則計數cnt[]陣列為:
索引
22
111
333
666
7777
55555
99999
計數
2
1
1
1
1
3
1
以下程式若點播編號 < 1000000 時可行{如以上資料}但若讀入的編號 >= MaxN 則會錯誤
例如輸入: 10 55555 666 7777 99999 55555 333 22 111 55555 22222222
#include <iostream>
using namespace std;
const int MaxN = 1000000;
int cnt[MaxN];
int main(void)
{
        int j,n,k;
        for(j=1;j<MaxN;++j) cnt[j] = 0; //全設為 0
        cin >> n;
        for(j=0; j<n; ++j)
        {
                cin >> k; // 讀入的點播號, k=22222222,則 cnt[22222222]超出範圍
                cnt[k] ++;  //該號碼 計數 +1
        }
        int p=1, m=cnt[p] ; // 找出計數最大的編號及個數
        for(k=2; k<MaxN; ++k)
        {
                if( cnt[k] > m ) // 點播數較多的記住
                {
                        m = cnt[k] ;  //記住目前最多的個數
                        p=k;          // 記住點播號存至 p
                }
        }      
        cout <<p<< " " << m<< endl;
        return 0;
}





b005:熱門點播
方法二:如何解決以上的問題
例如輸入: 10 55555 666 7777 99999 55555 333 333 111 55555 22222222
改成兩個陣列,一個num存點播號,一個cnt存各點播號的計數,
而且,每個點播號依讀入的順序另編序號(索引)
num索引
0
1
2
3
4
5
6
19
num
55555
666
7777
99999
333
111
22222222


cnt索引
0
1
2
3
4
5
6

cnt
3
1
1
1
2
1
1
0
0
因為 n最大為20,所以numcnt陣列不會超過20個元素
但如何將讀入的點播號轉成序號
{555551:序號06662:序號1、…、第2次讀到55555出現過:使用序號0}
宣告一個變數 now為下一個序號值,一開始設為 0
每讀入一個點播號k 就檢查陣列num[0] ~ num[now-1] 是否已有 k 這個號碼
以下程式可完成這個任務
程式表頭,宣告部份就省略…
先將cnt陣列清空:for(i=0; i<20; ++i) cnt[i]=0;
讀入n cin >> n;
接著迴圈讀入n個點播號k   for(i=0; i<n; ++i) { 有五行程式碼,說明不算 }
(1)讀入k      cin >> k;
  (2)以迴圈j檢查num           for(j=0; j<now; ++j)
  (3)   k出現在num中跳出:      if(k==num[j]) break;        
     // j<now 有出現過, j==now 沒出現過
  (4)若沒出現過將k存入num陣列中,now+1    if( j==now ) num[now++] = k;
  (5) 序號為 j 的編號 點播數加    cnt[j]++ ;

    //  序號j 因為若是j==now就是新的序號,或j<now就是找到曾出現的序號

0 意見:

張貼留言