輸入n個正整數的陣列X,
輸出其平均值,中位數及眾數。
(如有多個眾數則取最小者)
輸入:
第一行為數字n,代表陣列的個數。
第二行為以空格隔開的n個正整數。
輸入限制10 <= N <= 2500,且每個正整數<=10的5次方。
輸出:
分三行輸出平均值(mean),中位數(median),眾數(mode),
如解為小數,則輸出到第1位。
解題:
首先讀入後,先經過排序由小至大。
(這邊還是使用之前用過的qsort)
平均值->加起來除以n即可。
中位數->取n/2,整除的話,
答案是為x[n/2-1]+x[n/2+1-1]的一半,
否則解為x[(n+1)/2-1]。
(-1的原因是因為陣列由0開始,全部平移1單位)
留意%0.1lf可以保證輸出的小數點後面顯示1位。
眾數->在輸入值有限的狀況,使用類似bucket sort的方法。
直接開一個every_cnt[100000]並初始化,
接著依次讀出x[i]的值,並以every_cnt[x[i]]++達到記數的效果。
最後,遍歷各項有值的every_cnt,
經比較即可得出眾數為何。
這個方法較為占用記憶體,但除去前面sorting的部分,
後面進行記數以及查找均為線性的複雜度。
(記數為O(n),查找為遍歷x[0]~10^5)
Code:
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> int compare(const void *arg1, const void *arg2){ return (*(int *)arg1 - *(int *)arg2); } int main() { int n; scanf("%d\n", &n); int x[n]; double mean = 0.0; for(int i = 0; i < n; i++) { scanf("%d\n", &x[i]); mean += (double) x[i]; } mean /= (double) n; printf("%0.1lf\n", mean); qsort((void *)x, n, sizeof(int), compare); if(n % 2 == 1) printf("%d\n", x[(n+1)/2 - 1]); else printf("%0.1lf\n", (double)(x[n/2 - 1] + x[n/2+1-1])/2.0); int every_cnt[100000] = {0}; int max_n = x[0]; for(int i = 0; i < n; i++){ every_cnt[x[i]]++; } for(int j = x[0]; j < 100000; j++) { if(every_cnt[j] == 0) continue; if(every_cnt[j] > every_cnt[max_n]) max_n = j; } printf("%d\n", max_n); return 0; }
沒有留言:
張貼留言