Review of 2014 Qulification round problem A:Magic Trick

14 Apr 2014

For english studying, I traslate the problems into Japanese. Original english text is here

Problem A

最近あなたはマジックショーを観に行きました。あなたはその中のひとつの手品に 感銘を受けました。なので、あなたはその手品の種を見つけようと決めました。 まずマジシャンは16枚のカードを一列4枚ずつ4列の正方形状に並べます。 それぞれのカードは表面に1から16の異なる数字書かれています。 次にマジシャンはボランティアにカードを選んでもらい、 そのカードがどの列に入っているか教えてもらいます。

最後にマジシャンは16枚のカードをできる限り別の並び順で、再び正方形状に並べます。 もう一度、先ほどのボランティアにカードがどの列に入っているか尋ねます。

あなたはマジシャンのテクニックを理解するためにプログラムを書くことにしました。 プログラムは2つのカードの並びとボランティアの回答が与えられます。 最初の並びでの選択された数の列の番号と2つ目の並びでの選択された数の列の番号です。 列は上から下に順に1から4の番号が振られています。

あなたのプログラムはボランティアが選んだカードを当てなければいけません。 もしくは2つ以上のカードが選ばれたようになるか(マジシャンが失敗した)、 もしくはボランティアが矛盾した回答をしたように見えるか(ボランティアがずるをした)です。

Input

最初の一行はテストケースの数 T です。

テストケースは以下です。 一行目はの最初の質問の回答を表す1つの整数です。 続く4行は最初のカードの並びを表します。 それぞれ4つの整数が1つのスペースで区切られています。 次の一行は2つ目の質問の回答です。 そして続く4行には2つ目のカードの並びが同様の形で入っています。

Output

それぞれのテストケースに対して出力は”Case #x:y”の形式の一行です。 xはテストケースの番号です。(1はじまり) もし、ボランティアがひとつのカードを選んでいたら、yはカードに書かれた数になります。 もし、ボランティアが複数のカードを選んでいたようになっていたら、yは”Bad magician!”というクオート文字列になります。 もし、ボランティアが矛盾のあるカードを選んでいるようだったら、”Volunteer cheated!”というクオートなしの文字列になります。 テキストはきっちりそのままである必要があるので、ここの文字列をそのままコピーアンドペースとするようにしてください。

Limits

1 ≤ T ≤ 100. 1 ≤ 両方の質問の回答 ≤ 4. それぞれのならびには1から16の数がちょうど一回ずつでてきます。 Each number from 1 to 16 will appear exactly once in each arrangement.

Here is My answer: I think this problem is very simple.

#include <cstdio>
#include <algorithm>
#include <cassert>
using namespace std;
int main()
{
int count;
scanf("%d", &count);
for (int i = 1; i <= count; i++) {
int before_row, after_row;
int cards[4][4];
int candidates[4];
scanf("%d", &before_row);
// printf("%d\n", before_row);
for (int r = 0; r < 4; r++) {
scanf("%d %d %d %d", &cards[r][0], &cards[r][1], &cards[r][2], &cards[r][3]);
// printf("%d %d %d %d\n", cards[r][0], cards[r][1], cards[r][2], cards[r][3]);
}
for (int c = 0; c < 4; c++) {
candidates[c] = cards[before_row-1][c];
}
scanf("%d", &after_row);
// printf("%d\n", after_row);
for (int r = 0; r < 4; r++) {
scanf("%d %d %d %d", &cards[r][0], &cards[r][1], &cards[r][2], &cards[r][3]);
// printf("%d %d %d %d\n", cards[r][0], cards[r][1], cards[r][2], cards[r][3]);
}
int match = 0;
int num = -1;
for (int c = 0; c < 4; c++) {
for (int j = 0; j < 4; j++) {
if (candidates[c] == cards[after_row-1][j]) {
match++;
num = candidates[c];
}
}
}
switch (match) {
case 0:
printf("Case #%d: Volunteer cheated!\n", i);
break;
case 1:
printf("Case #%d: %d\n", i, num);
break;
default:
printf("Case #%d: Bad magician!\n", i);
break;
}
}
}

Tweet