アプリ版:「スタンプのみでお礼する」機能のリリースについて

今、学校の課題で自分にとっては難しい課題がでています

本当は取る予定の科目でなかったため大変で・・・・・

とりあえずとっかかりすら見つかりません(゜ー゜;Aアセアセ

以下、課題です・・・・

ハーフカード : 数値を二分の一倍します

反転カード  : 数値の符号を反転します

二乗カード  : 数値を二乗します

プレイヤーは配られたすべてのカードを一回ずつ使います。(今回の場合三枚です)
たとえば「二乗」二枚と「ハーフ」「反転」を一枚ずつの合計4枚のカードが配られ、出題された整数が3、目標値が16のとき以下の手順でプレイヤーの勝利となります。

3 → 二乗 → 9 → ハーフ → 4 → 反転 → -4 → 二乗 →16

とっかかりだけでいいので、これからの方針などを教えていただければ嬉しいです
↑くわしく教えていただければ最高なのですがそれは高望みですよね・・・・・

とりあえず、どうぞよろしくお願いします!! m(。≧Д≦。)m

A 回答 (9件)

一応作ってみた。




enum cardKind {isHalf, isHanten, isJijou};
cardKind tefuda[] = {isJijou, isJijou, isHalf, isHanten};

int calc(int start, int num)
{
for (int i = 0; i < num; i++)
{
switch(tefuda[digit[i]])
{
case isHalf : start /= 2; break;
case isHanten : start = -start; break;
case isJijou : start = start * start; break;
}
}
return start;
}

を追加して、
main() を、


int main()
{
int num = 0;
const int n = sizeof(tefuda) / sizeof(tefuda[0]);
listInit(n);

int start;
int terget;

std::cout << "start = ";
std::cin >> start;

std::cout << "terget = ";
std::cin >> terget;

while(get())
{
if (calc(start, n) == terget)
{
num++;

std::cout << "case No. " << num << " find !: from " << start;
for(int i = 0; i < n; i++)
{
switch(tefuda[digit[i]])
{
case isHalf : std::cout << " -> ハーフ"; break;
case isHanten : std::cout << " -> 反転"; break;
case isJijou : std::cout << " -> 自乗"; break;
}
}
std::cout << " to " << terget << "\n";
}
}

if (num == 0) std::cout << "can not found\n";
return 0;
}

に入れ替えると、それらしい動きはします。
ただし、大きな欠陥があって、「自乗」が2枚ある関係、全く同じ答えが2回でます。
    • good
    • 0
この回答へのお礼

お礼が遅くなりましたが、すごく参考になりました!!

同じように作ることはできませんが所々参考にさせていただきたいと思います

お急がしい中本当にありがとうございました!!

お礼日時:2010/07/01 10:49

> 本当は取る予定の科目でなかったため大変で・・・・・



取る気のない科目の課題でしょ?
どこの誰ともわからん人に丸投げしてまでやる価値ないんじゃありません?

> とりあえずとっかかりすら見つかりません

取る気がないから授業内容ろくすっぽ理解してないってことで、
課題提出して単位取ったって何の意味もないじゃないですか。
    • good
    • 0
この回答へのお礼

正直とっかかりすら見つからないというのは言い過ぎました

理解ある方からの助言のようなものをいただいて、自分の作ったものに追加できたらと思っていました

すいません
ちょっとした方便でした

お礼日時:2010/07/01 10:51

すべての順列(高々n!通り)を生成し、計算して目標値と一致するものを採用する。

    • good
    • 0

学校の課題。

。。
その課題のとっかかりが分からない。
課題を出した人にそれを訴えるのが常識ではないのか?
「とっかかりさえわからない」 ということを先生に隠したままここで得た回答を提出して誰のためになるのか。
「そこがわからないんだ」 というのを先生に知ってもらうことのほうが今のあなたにとって何十倍も得なのですよ。

それとも既に相談したが 「そんなもんはネットで誰かに教えてもらえ」 とでも言われたか。
    • good
    • 0
この回答へのお礼

他の方にも回答したのですがとっかかりすら見つからないというのは方便です

誤解を生んでしまうような書き方をして申し訳ありませんでした

これからはめんどくさがらず詳細に記述したいと思います

お礼日時:2010/07/01 10:53

このゲームを作成することが課題なのか、


それともこのゲームにおける勝利手順を導き出すのが課題なのか、
どちらなのでしょうか?
    • good
    • 0

「これからの方針」と書かれてますが, 結局今できていることは「問題の理解」ですよね.


で, 多くの場合ここから
1. 「自分ならこの問題をどのように解くのか」を考える
2. それを (陽にあるいは陰に) アルゴリズムとして記述
3. 特定の言語 (この問題では C) でコーディングする
という方針をとることになるかと.
    • good
    • 0
この回答へのお礼

参考にさせていただきました

ありがとうございました

お礼日時:2010/07/01 10:54

どのあたりまでの条件(たとえば、カードの最大枚数とか)が仮定できるかによりますが、結構難しいですね。


一応、ぱっと作っただけの、「すべての順列」をリストアップするところだけ考えてみました。

これで、digit[0], digit[1], ... に 0 から カードの枚数 - 1 の順列が順次得られますから、その順番でカードを試してみるというのもひとつの手かなと思います。

順列プログラムは、単純に多倍長で 0, 1, 2, .... を作って、各桁で重複した数値がないかを数えるだけのものなので、効率はかなり悪いです。



#include <iostream>

int digit[100];
int check[100];
int maxDigit;

void listInit(int n)
{
maxDigit = n;
for(int i = 0; i < maxDigit; i++)
{
digit[i] = 0;
}
}

int get()
{
int i;
while(1)
{
int pos = 0;
while(1) // まず、候補の数列をひとつ作る
{
digit[pos]++;
if (digit[pos] >= maxDigit)
{
digit[pos] = 0;
pos++;
if (pos >= maxDigit) return 0;
continue;
}
else
break;
}

// それが、順列として条件を満たしているか確認する
for (i = 0; i < maxDigit; i++)
{
check[i] = 0;
}

for (i = 0; i < maxDigit; i++)
{
if (check[digit[i]] == 1) // その数字は既に現れている
break;

check[digit[i]] = 1;
}

if (i == maxDigit) // 全部の数字が一度だけ現れている(はず)
return 1;
}
}

int main()
{
const int n = 4;
int num = 0;

listInit(n);
while(1)
{
if (get())
{
num++;
std::cout << "No. " << num << ": ";
for(int i = 0; i < n; i++)
{
std::cout << digit[i];
}
std::cout << "\n";
}
else
break;
}

return 0;
}
    • good
    • 0

総当たりで考えればいい訳です。


カードを出す順序について、考えられるケースは3枚を全て使いきるという事から3枚×3回で9通りです。
全てのケースを出したら、出題された数を入れてみて目標値が出るケースがあるかどうかを探すだけです。
    • good
    • 0

すべての順列を計算すればいいです

    • good
    • 0

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