SRM 544 - Div I
Single Round Match 544 Round 1 - Division I
http://community.topcoder.com/stat?c=round_overview&er=5&rd=14736
Problem | Status | Points | |
---|---|---|---|
275 | ElectionFraudDiv1 | Unopened | |
500 | FlipGame | Passed System Test | N/A |
1000 | SplittingFoxes | Unopened |
- 練習
- Div I Mediumがそんなに難しくないという話を聞いたので、挑戦した
FlipGame
http://community.topcoder.com/stat?c=problem_statement&pm=11974&rd=14736
- 26分
- 貪欲法を用いた
- 左上から右下まで任意の最短経路を通る
- 興味があるのは経路の左側だ
- 太線の意味合いを最短経路から凸包とする
- 経路の左側の数値を反転する
- これを繰り返して全ての数値を0にする問題
- 直感的に各行の数値のすぐ右側を通れば最適になりそうだ
- 数値を反転する
- 結果の範囲は確実に狭くなるはず
実装は以下(システムテスト済み)。
class FlipGame { public: int minOperations(std::vector<std::string> board) { int h = board.size(); for (int c = 0; ; c ++) { if (check(board)) return c; std::vector<int> tail; for (int x = 0, y = 0; y < h; y ++) { int pos = board[y].rfind('1'); if (pos != std::string::npos) { tail.push_back(x = std::max(x, pos + 1)); } else { tail.push_back(x); } } for (int y = 0; y < h; y ++) for (int x = 0; x < tail[y]; x ++) if (board[y][x] == '0') { board[y][x] = '1'; } else { board[y][x] = '0'; } } return -1; }; private: bool check(const std::vector<std::string>& board) const { EACH(it, board) if (it->find('1') != std::string::npos) return false; return true; }; };
- SRM544 Div1 Medium(500) FlipGame - 赤コーダーになりたいを読む
- charの'0'と'1'をXORで入れ換えていて、衝撃を受けた
for ( int x=0; x<cx; x++ ) board[y][x] ^= 1;
- これはすごい
- 全体的にも簡潔だ
- XORは'A'と'B'、'a'と'b'では成立しないので注意が必要
- すこし考えてみよう
- 2と3を交互に入れ換える実装に近い
c = 'b' - c + 'a';
- んー
- よさそうだ