AOJ ITP1_11_Aをやっていて結構困ったので備忘録的に書いておく。
問題はページに飛んで各自で見ていただきたい。
できるようにすべきこと
・方角を与えてサイコロを回転させる
・上面の数値を返す
実現に向けて最初にやろうとしたこと
・各面の数値をメンバ配列に入れておく
・上面になっている面の番号を変数に記録しておく(最初は1
)
(各面には数字とは別に一意な番号が振ってある)
いざ回転
回転させる際は、現在の上面の番号と移動の方角から次の上面の番号を求める。
⇒だめでした
回転の仕方によって番号の推移が違うことが判明。
S方向に転がしていって6を上面にしたときと、E方向に転がしていって6を上面にしたときでは番号の配置(ひいては面の配置)が違う。
動き方によって処理を変えないといけない?
ブレークスルー
「上の面が何番かを記録しておく」のではなく、「回転するたびに数字を全部回転に合わせて実際に動かす」。
(最初に考えた方法よりもむしろプリミティブ。でもこっちの方が正しい)
コードも載せておく。
2015/07/12 他の記事を書くにあたり少し修正。
(operator[]()
の追加、top()
の削除)
class dice{
public:
explicit dice(int in[6]){
for(int i=0;i<6;i++){
v[i]=in[i];
}
}
void mov(const char c){
int buf;
switch(c){
case 'N':{
buf = v[0];
v[0] = v[1];
v[1] = v[5];
v[5] = v[4];
v[4] = buf;
break;
}
case 'E':{
buf = v[0];
v[0] = v[3];
v[3] = v[5];
v[5] = v[2];
v[2] = buf;
break;
}
case 'W':{
buf = v[0];
v[0] = v[2];
v[2] = v[5];
v[5] = v[3];
v[3] = buf;
break;
}
case 'S':{
buf = v[0];
v[0] = v[4];
v[4] = v[5];
v[5] = v[1];
v[1] = buf;
break;
}
}
}
int operator[](size_t i){return v[i];}
private:
int v[6];
};
上面の数字を得るにはdice
オブジェクトd
について、d[0]
を呼べばよい。
課題
・方角ごとに処理を書くのはめんどい。
(何かのコンテナで解決できないだろうか)