SRM316 div2
easy
簡単すぎて申し訳ない.
string getMessage(string text) { string ans = ""; istringstream iss(text); string tmp; while(iss >> tmp) { ans += tmp[0]; } return ans; }
medium
問題把握に時間かかり過ぎ.
int fewestClicks(string messages, int low, int high) { int sz = messages.size(); int mini = INF; for(int k = low; k <= high; k++) { int tmp = (int)((sz-0.5)/k); //in advance add "advance" operation number for(int i = 0; i < (sz-0.5)/k; i++) { //whatever int k is ,never do err exception of out_of_range. string str = messages.substr(i*k, k); int cnt = count(str.begin(), str.end(), 'D'); int inc = min(cnt, 1+(int)str.length()-cnt); tmp += inc; if(inc) tmp++; } mini = min(mini, tmp); } return mini; }
difficult
あれ、かんたん?ようするに、深さがどれだけかわかればいいんじゃない?
と思ってキューで組んだら問題の読み間違いで違うかった.やっぱり再帰は難しい.
おそらく、いつも、
ans+=dfs(node);
ってしてるからすごく時間がかかったのだと思う.反省.
要するに時間のかかりそうなノードから先に伝達しちゃいましょうという問題.スタックを使うのは想像に難くない.
再帰関数使えばいいわけね。
class SpreadingNews { private: vector<int> arr[51]; int dfs(int node); public: int minTime(vector <int> supervisors) { int sz = supervisors.size(); //子孫ノードを格納 for(int i = 1; i < sz; i++) { arr[ supervisors[i] ].push_back(i); } return dfs(0); } }; int SpreadingNews::dfs(int node) { vector<int> tmp = arr[node]; int sz = tmp.size(); vector<int> cost; if(sz == 0) return 0; //※ for(int i = 0; i < sz; i++) { int c = dfs(tmp[i]); //int c += dfs(tmp[i])とかしなくてよい。 /*int c = 0; c += dfs(tmp[i]);*/ //と同値. cost.push_back(c); } sort(cost.rbegin(), cost.rend()); //微妙に行き当たりばったり法.ここで順番も含めたnodeのコストが確定する. for(int i = 0; i < cost.size(); i++) { cost[i] += (i+1); } return *max_element(cost.begin(), cost.end() ); }
//※最初からこうしておけば話は早い. if(sz == 0) return 0; for(int i = 0; i < sz; i++) { cost.push_back(tmp[i]); }