SRM570に参加。何とかEasyだけそこそこの時間で解ききってちょっとレート上昇。
http://community.topcoder.com/stat?c=problem_statement&pm=12427
問題
整数値Tと整数値配列Aが与えられる。
ロボットは最初(0,0)にいて上を向いている。整数値配列Aの各要素Bについて、ロボットは向いた方向にBマス進んだうえ、B回だけ90度右回転する。
このような処理を配列Aの全要素順番に適用し、かつそれをT回繰り返した場合の原点からのマンハッタン位置を答える。
解法
まず1周分処理してみる。その時の向きに応じてその後の処理を決める。
- 1周後また上を向いていたら、その位置をT倍すればよい。
- 1周後下を向いていたら、もう1周したらもとに戻る。よってTが偶数なら原点、そうでないなら1周分の位置に行く。
- 1周後左または右を向いていたら、4周したらもとに戻る。よって答えは(T%4)周分の位置に等しい。
class RobotHerb { public: long long getdist(int T, vector <int> a) { int i; ll rot=0,cr=0; ll x=0,y=0,tx,ty; FOR(i,a.size()) rot += a[i]; FOR(i,a.size()) { if(cr==0) y+=a[i]; if(cr==1) x+=a[i]; if(cr==2) y-=a[i]; if(cr==3) x-=a[i]; cr+=a[i]; cr%=4; } tx=x;ty=y; if(cr==0) { tx=x*T; ty=y*T; } else if(cr==1 || cr==3) { if(T%4==0) tx=ty=0; else if(T%2==0) { tx=x+y; ty=y-x; } } else if(cr==2) { if(T%2==0) tx=ty=0; } return abs(tx)+abs(ty); } };
まとめ
ほかの解法を見てるともっとスマートなものが多い。
まず最初の1周を向き毎に分岐するのではなくdx,dy配列を使ったりとか。
また、1周後上向き以外は、(T%4)周分再度繰りかえすとか。
うーん、そこら辺のテクニックがあればもっと速く書けそうだ。
今回Mediumが550ptだったし、Easy早解き合戦の時は簡単な書き方を考えないとダメだね。