質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

4217閲覧

嘘つき族と正直族の問題

退会済みユーザー

退会済みユーザー

総合スコア0

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

3クリップ

投稿2020/02/05 10:29

ある村に,Aさん,Bさん,Cさん,Dさんの4人がいました.このうち2人は嘘つき族であり,このうち2人は正直族であることが分かっています.嘘つき族は必ずうそをつき,正直族は必ず正直に答えます.彼らは,論理的であり,ミスはありません.
あなたの手元には, 1,2,3,4と書かれた4枚のカードがあります.同じ数字が書かれたカードはありません.そこからランダムに選んで,一人1枚ずつ,彼らに渡しました. 彼らは,以下のように発言しました.
Aさん:私のカードは,偶数です.
Bさん:私のカードは,3か4のどちらかです.
Cさん:Bさんは,正直族です.
Dさん:私のカードは,1です.
彼らに配られた可能性のあるカードの数字と,誰が嘘つき族/正直族かを表示するプログラムを作成します.
以下が現在のコードです.

C++

1#include<iostream> 2#include<string> 3using namespace std; 4 5int card_a, card_b, card_c, card_d; 6int liar_a, liar_b, liar_c, liar_d; 7 8void output() { 9 cout << "配られたカード: "; 10 cout << card_a << ", " << card_b << ", " << card_c << ", " << card_d << ", "; 11 cout << "正直族[1],嘘つき族[0]:"; 12 cout << liar_a << ", " << liar_b << ", " << liar_c << ", " << liar_d << endl; 13} 14 15int check() { 16 17} 18 19int main() { 20 for (card_a = 1; card_a < 5; card_a++) { 21 for (card_b = 1; card_b < 5; card_b++) { 22 if (card_b != card_a) { 23 for (card_c = 1; card_c < 5; card_c++) { 24 if (card_c != card_a && card_c != card_b) { 25 for (card_d = 1; card_d < 5; card_d++) { 26 if (card_d != card_a && card_d != card_b && card_d != card_c) { 27 if (check() == true) { 28 output(); 29 } 30 } 31 } 32 } 33 } 34 } 35 } 36 } 37 cout << "プログラム終了時は何かを入力" << endl; 38 int x; cin >> x; 39 return 0; 40} 41

ここまでできたのですが,条件を満たすかどうかを判定する関数checkをどのように書けばいいのかわからないので教えてください.よろしくお願いします.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2020/02/05 11:13

この問題の出典を追記して下さい。
退会済みユーザー

退会済みユーザー

2020/02/05 11:14

プログラミング演習支援システムというサイトです。
Zuishin

2020/02/05 11:31

佐賀大学の課題ですか。
guest

回答3

0

4人のうちの誰が正直で誰が嘘つきなのか?という点に関しての取り得るすべての組み合わせに関して,総当たりで
パターン{card_a, card_b, card_c, card_d}が矛盾するかしないかをチェックすればよいのではないでしょうか.


上記をコード化すると,例えばこんなかと.

C++

1//※戻り値がintである意味がわからんのでboolにしたが. 2bool check() 3{ 4 static const bool Hypothesis[][4] = 5 { 6 { true, true, false, false }, { true, false, true, false }, { true, false, false, true }, 7 { false, true, true, false }, { false, true, false, true }, 8 { false, false, true, true } 9 }; 10 11 for( const auto &H : Hypothesis ) 12 { 13 if( ((card_a&0x01)==0) != H[0] )continue; //A 14 if( (card_b==3 || card_b==4) != H[1] )continue; //B 15 if( (H[1]) != H[2] )continue; //C 16 if( (card_d==1) != H[3] )continue; //D 17 //liar_a等の値の仕様がわからんが,こうすればいいのか? 18 liar_a = H[0]; liar_b = H[1]; liar_c = H[2]; liar_d = H[3]; 19 return true; 20 } 21 return false; 22}

投稿2020/02/05 10:39

編集2020/02/06 03:34
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/05 10:41

どのようなコードを書いたらいいでしょうか?教えてください。よろしくお願いします。
fana

2020/02/05 10:57

低評価理由を明記願いたいです. 話が間違っているのであれば,質問者に対してこれ以上この回答内容に即した話を続けるわけにもいきませんので.
fana

2020/02/05 11:00

(というわけで,ダメな理由がわかるまでサスペンド)
SaitoAtsushi

2020/02/05 13:36

質問者は Teratail の趣旨をわかっていないように見えます。 Teratail は質問に対して回答することを趣旨とするサービスであり、解となるコードを求めることは推奨されません。 それは質問というよりは代わりにやって欲しいという要求です。 https://teratail.com/help/avoid-asking 説明のためにコードを提示することはありますが、質問者の替わりに課題を解くことはしません。
fana

2020/02/06 03:47 編集

時間を設けてみたが,低評価理由は書かれない模様. 質問者のコメントや雑すぎるマルチポストなどの様子を鑑みると,正直,コード(のようなもの)を書くことはためらわれるのだが,無言低評価君(何故か増えている)が少しでも理由を書きやすくなるよう,あえて私の回答内容をコード化してみた. コード内容の間違いがあれば指摘願いたい. コードを記す行為自体に否定的評価を下すのであればその旨を明記されたい. To質問者様:提示したコードは全く動作(というかコンパイルすら)確認されていない殴り書きである点に注意されたい.
fana

2020/02/06 03:46

(仮に,低評価理由が「お前の態度がなんとなく気に入らない」みたいな理由だとしても,やはり明記願いたい. そういう理由によるものなのだとわかるだけでも,理由が書かれないよりはずっと良い.)
guest

0

ヒントです。

C++

1int check() { 2 static bool t[6][4] = { /* ここに嘘つき族2人、正直族2人の全パターンを書く */ }; 3 for (bool *p = *t; p < t[6]; p += 4) 4 if (!(card_a&1)==p[0] && (card_b>=3)==p[1] && !p[1]==p[2] && (card_d==1)==p[3]) { 5 liar_a = p[0], liar_b = p[1], liar_c = p[2], liar_d = p[3]; 6 return 1; 7 } 8 return 0; 9}

理解できたら、解答を書いてください。
理解できなかったら、どこが分からないのかを質問してください。

投稿2020/02/05 14:50

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/05 15:06

全パターンを書くとありますが,どのような形式で書けばいいのでしょうか?教えてください.お願いします.
guest

0

ベストアンサー

嘘つきなら反対を答える関数を用いると簡潔に実装できるかと思います。

C++

1// 嘘つきなら反対を答える 2bool get_answer( 答える人, 嘘つきな人たち, 答え){ 3 if( 答える人が嘘つきな人たちに含まれる){ 4 答え = !答え; 5 } 6 return 答え; 7} 8 9 10bool check( 嘘つきな人たち, 各人のカード) 11{ 12 return get_answer( A, 嘘つきな人たち, Aさんの命題) & 13 get_answer( B, 嘘つきな人たち, Bさんの命題) & 14 get_answer( C, 嘘つきな人たち, Cさんの命題) & 15 get_answer( D, 嘘つきな人たち, Dさんの命題); 16}

投稿2020/02/05 12:02

編集2020/02/05 12:03
can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/05 12:26

int型のcheck関数のみで成立させるにはどうしたらよいでしょうか?
can110

2020/02/05 13:07

戻り値がintでもboolでも中身は変えなくてもよいです。 引数を渡すのがいやなら外部変数を使えばよいのでは?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問