SRM 538 DIV1 Medium TurtleSpy
http://apps.topcoder.com/stat?c=problem_statement&pm=11704&rd=14729
問題
命令列が与えられる
"right X", "left X" (X: nat, X <= 359)
右・左にX度回転する。
"forward X", "backward X" (X: nat, 1 <= X <= 1000)
現在の方向に対して前・後にX進む。
これらの命令を入れ替える。ただし"right", "left"は含めなくてもよい。
この命令列を実行して現在の位置からできるだけ離れたい。
最大の距離を答えろ
回答
まず、
最初にforwardを全部使っちゃって、
できるだけ180度に近い角度に回転し、
最後にbackwardで進む。
という戦略が立てられる。
問題はできるだけ180度に近い角度に回転する部分だが、これは単純な、(bool[i][j] := i番目の回転命令まで見た時、j度が可能かどうか) なDPでできる。
コメント
回答・解説は前に見た。
left,rightを含まなくてもいいというのが最初問題読めなかった。Exampleから推測しろ
コード
#include <string> #include <vector> #include <algorithm> #include <set> #include <map> #include <queue> #include <iostream> #include <sstream> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) #define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) #define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i)) #define aut(v, x) __typeof(x) v = (x) #define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it) #define all(o) (o).begin(), (o).end() #define pb(x) push_back(x) #define mp(x,y) make_pair((x),(y)) #define mset(m,v) memset(m,v,sizeof(m)) using namespace std; typedef long long ll; typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pii> vpii; const int INF = 0x3f3f3f3f; const ll INFL = 0x3f3f3f3f3f3f3f3fLL; struct TurtleSpy { double maxDistance(vector <string> commands) { double b = 0, r = 0; vi v; each(i, commands) { stringstream s(*i); string c; int x; s >> c >> x; if(c == "forward") { r += x; }else if(c == "backward") { b += x; }else if(c == "left") { v.pb(360-x); }else if(c == "right") { v.pb(x); } } static bool dp[51][361]; mset(dp, 0); dp[0][0] = true; int m = v.size(); rer(i, 1, m) rer(j, 0, 359) { dp[i][j] |= dp[i-1][j]; dp[i][(j+v[i-1])%360] |= dp[i-1][j]; } rep(i, 360) if(dp[m][i]) cout << i << endl; rer(i, 0, 180) { if(dp[m][180-i] || dp[m][180+i]) { double xx, yy; xx = r + b * cos(i / 360.0 * 3.1415926535897932384626433832795028841971693993751058 * 2.0); yy = b * sin(i / 360.0 * 3.1415926535897932384626433832795028841971693993751058 * 2.0); r = hypot(xx, yy); break; } } return r; } };