どうやって合格者の人数を把握するか? という方法について考えます.
i番目の人物の点数がs点であるとき,この人物を座標(s,i)に立たせることを考えてみます.
int s[10] = {91, 46, 68, 72, 89, 52, 94, 70, 43, 61};
に対しては,10人の立ち位置は下図の青い点の位置になります.
ここで仮に合格点が80点だったとしましょう.
この場合,あなたが図内の赤丸の位置(80,0)に赤矢印の方向を向いて立ったときに,あなたから見て右手側(または真正面)にいるやつらは合格者であり,左手側に突っ立っているやつらは不合格者なのです.
この例では図を見れば合格者は3人であることがわかります.
上記の話を実装します.
「右手側にいるか,左手側にいるか」というのは,外積を使えば判断できます:
赤丸から各青丸に向かうベクトルと赤矢印のベクトルとの外積(※)の符号を見れば,それぞれの青丸がどちら側にあるかがわかります.
(※:2次元のベクトル(x,y)を,3次元ベクトル(x,y,0)と見立てて外積を計算した結果のz成分)
typedef struct Vec { int x,y; } Vec;
int CrossProd( const Vec *pV1, const Vec *pV2 ){ return pV1->x * pV2->y - pV1->y * pV2->x; }
int calc_pass(int data[], int n, int g )
{
int i;
int count = 0;
Vec V2 ={0,1}; //赤矢印
for( i=0; i<n; ++i )
{
Vec V1 = { data[i] - g, i+1 }; //赤丸→青丸 のベクトル
if( CrossProd( &V1, &V2 ) >= 0 ){ ++count; }
}
return count;
}
int main(void)
{
int s[10] = {91, 46, 68, 72, 89, 52, 94, 70, 43, 61};
int g = 80;
printf( "%d\n", calc_pass( s,10, g ) );
return 0;
}
なお,このコード例では,関数calc_pass
の仕様を以下のように変更しました.
- 引数に閾値
g
を追加
- 戻り値をintにした(人数を返すのであれば,その型をdoubleとする意味がわからなかったので)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/30 07:21
2020/11/30 07:34
2020/11/30 07:50 編集
2020/11/30 07:46
2020/11/30 07:51