プロが教えるわが家の防犯対策術!

課題を解いて欲しいです。。。

パーティでビンゴ大会を行おうとしている。
そのビンゴでは1~n の数字をコンピュータを用いてひとつずつ取り出すのだが、そのプロ
グラムがまだ完成していない。
1. n=200 としたとき、あなたが考えた実行方法をコーディングしなさい。
2. インターネットを用いて最適と思われる方法を探しだし、同様に n=200 としてコーデ
ィングしなさい。
3. 1 と2 の方法について実行時間を計測しなさい。
4. 1 と2 の方法をそれぞれ考察しなさい。
ただし、1、2、共にそれぞれどのような考え方で行ったか、説明を付随する。

全くわからないのでお願いします。

A 回答 (16件中1~10件)

> ANo.10


map使うまでもなし。setで充分。

#include <iostream>
#include <set>
#include <cstdlib>

int main() {
std::set<int> doneNumber;
const int numOfBingo = 200;
// インデックスとしては、1 - 200 じゃなくて、 0 - 199 を使う
while ( doneNumber.size() < numOfBingo ) {
int n = std::rand(); // ひとつ番号を出してみて
// その場号が範囲内かつまだでてなければ出力する
if ( n < numOfBingo && doneNumber.insert(n).second ) {
std::cout << (n + 1) << "\n";
}
}
}

# アルゴリズムは依然として最低ですが ^^;
    • good
    • 0

計算量一緒なのに質問1の回答と断定されてもループが一個多くなるからたしかにオーバーヘッド増えるし負けましたすいません勘弁してくださいごめんなさいだからむきにならないでベタ張りしてるのが痛すぎて読む気になれなかったんですごめんなさい無職でもコード書く時間無かったんですすいませんでした0~i(n<100)とかするより1~200にすればiMAXとか余計な変数使わなくて良いからC言語なら7Byte余分にGEEEEEEEEET!とか言わないから許してくださいごめんなさい7Byteは与太じゃないからゆるしてくださいそもそも課題やってください系の質問に書いてる時点で釣りだろとか言いませんのでごめんなさいすいませんでしたゆるしてくださいいろんなところでこういう質問に自分で考えろとか説教たれてる無職が見てていたたまれなかったんですごめんなさいすいません自分も無職でした本当にすいませんでした許してください。

    • good
    • 0

No.14 さんへ


質問者さんの質問に回答出来るのは、質問 2 のみだと私は思っています。
なので、私は No.7 No.11 で最適と思われる方法を回答させて頂きました。
他の言語にてソースを提示する事は、質問 2 に関して問題は無いはずです
No.14さんは、質問 1 の回答をされておられる様ですが、それこそ、
それは質問者さんが、自分で考えなければ意味が無い部分の回答だと思いますよ
    • good
    • 0

学校の課題ならC以外の言語分かってるとは考えにくいだろうが。


なにベタ書きしてんの?
英語分からない子に英語でこういうんだよって言ってるのと同じだろうが、
手順書くべきだろ。

手っ取り早くCで実装できるのは
・長さ200の配列を用意する、各値はインデックスと同じでかまわない。
・0~199の乱数を複数回発生させる。
・乱数発生2回毎に1回目と2回目の値をインデックスとして配列の内容を入れ替える。
・頭から出力。
    • good
    • 0

> A No. 12



おお、set::insert() に返り値があるなんて初めて気がつきました。
重複した要素の挿入は、失敗なんですね、扱いとして。なんとなく「無視されるだけ」というイメージでした。
    • good
    • 0

No.7 です



No.7で書いた、最適と思われるコードを EXCEL のVBA で書いておきます。
Sub test()
Dim i As Integer
Dim iMax As Integer
Dim n(200) As Integer
Dim r As Integer

iMax = 199
'
'n[200]等の配列を用意し、n[0]~n[199]に 1~200 の数字を入れる
For i = 0 To iMax
n(i) = (1 + i)
Next i
'準備OK

For i = iMax To 0 Step -1
' 0 ~ i の範囲で乱数を発生させる
r = Int((i + 1) * Rnd())

' Sheet1.セルA 列 1行目からに n(r)の中身をセット
Worksheets("Sheet1").Cells(1 + (iMax - i), "A").Value = n(r)

' n(r) に n(i)の値をセット
n(r) = n(i)
Next i
End Sub

これだけです。
    • good
    • 0

No.5 です。


C++で(というか、STLで)書いてみたもの。

でも、No.5 と見かけが全然変わらないのは、C++とSTLの素性の良さかな。
ロジックは、あいかわらず「ほぼ最低」ですが。

#include <cstdlib>
#include <iostream>
#include <map>

int main()
{
std::map<int, bool> doneNumber;
const int numOfBingo = 200;

int i;
// インデックスとしては、1 - 200 じゃなくて、 0 - 199 を使う
while(1)
{
int n = std::rand(); // ひとつ番号を出してみて
if (n < numOfBingo) // numOfBingo 未満ならいけそう
{
if (! doneNumber[n]) // その場号がまだでてなければ、
{
doneNumber[n] = true; // 番号がでたという印をつけて
std::cout << (n + 1) << "\n";
}
}
for(i = 0; i < numOfBingo; i++)
{
// 全部の数字が出たかどうか確認するためのループ
if (! doneNumber[i]) break; // まだ出てない数字があれば、ループを抜ける
}

if (i >= numOfBingo) // 全部カウントした == 出てない数字はない
break;
}

return 0;
}
    • good
    • 0

> 課題の答えとして提出するには高度すぎるというような回答が好きです。



では得意満面にC++で。

#include<iostream>
#include <algorithm>
#include <array>
#include <numeric>

using namespace std;

int main() {
array<int,200> bingo;
iota(bingo.begin(), bingo.end(), 1);
random_shuffle(bingo.begin(), bingo.end());
for_each(bingo.begin(), bingo.end(), [](int n) { cout << n << ' '; });
}
    • good
    • 0

最近は得意満面になって回答ベタ書きする人が増えましたね。


前回見かけたベタ書き解答は誤回答だったですけど…。

質問者さんのためを思うなら、スマートで適切なヒントを出すべきだと思います。

それか、回答としては間違ってないけど
課題の答えとして提出するには高度すぎるというような回答が好きです。
    • good
    • 0

多分最適と思える方法


n[200]等の配列を容易し、n[0]~n[199]に 1~200 の数字を入れる
準備OK

1回目1個取り出し
0~199 の範囲で乱数を発生させる
仮に 30 だった場合、
画面に n[30]の中身を表示し(画面 n[30]の中身の 31 を表示)
n[30]に n[199]の値を入れる(n[30] の中身は200になる)

2回目1個取り出し
0~198 の範囲で乱数を発生させる ← 範囲を1個狭める事が重要
仮に 50 だった場合、
画面に n[50]の中身を表示し(画面 n[50]の中身の 51 を表示)
n[50]に n[198]の値を入れる(n[50] の中身は199になる)

3回目1個取り出し
0~197 の範囲で乱数を発生させる ← 範囲を1個狭める事が重要
仮に 197 だった場合、
画面に n[197]の中身を表示し(画面 n[197]の中身の 198 を表示)
n[197]に n[197]の値を入れる(n[197]の中身は変わらない)



最適である理由
事前にシャッフルしない
既に出たか確認しない
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!