3050 Hopscotch
概要
5×5のマスに整数が書いてある。
適当なマスからスタートして4方好きな方向に5回移動する。
そのとき到達した6個のマスを順に並べてできる数は
何個あるか答える。
例えば、1→1→1→1→2→1と移動したら111121が得られる。
方針
(4^5)*5*5だから全部やっても大丈夫な気がしたけどTLEもらったので、
メモ化探索してみる。
set
何度か同じ引数でdfs(r, c, ith)を呼び出すことになるので、返り値はmemo[r][c][ith]にとっておいて、計算済みならばmemoの値を返す。
最初vector
#include<cstdio> #include<set> #include<string> #include<stdlib.h> #include<sstream> using namespace std; int grid[5][5]; set<string> memo[5][5][7]; int dr[4] = {0, -1, 0, 1}; int dc[4] = {1, 0, -1, 0}; bool valid(int r, int c) { return r >= 0 && r < 5 && c >= 0 && c < 5; } set<string> dfs(int r, int c, int ith) { if (!memo[r][c][ith].empty()) { // 探索済みならmemoを返す return memo[r][c][ith]; } set<string> ret; stringstream ss; ss << grid[r][c]; string str; ss >> str; if (ith == 1) { // ラストのマス。自分自身を返す ret.insert(str); } else { for (int i = 0; i < 4; ++i) { if (valid(r+dr[i], c+dc[i])) { set<string> tmp = dfs(r+dr[i], c+dc[i], ith-1); set<string>::iterator it = tmp.begin(); while (it != tmp.end()) { ret.insert(str+*it); ++it; } } } } return memo[r][c][ith] = ret; } int main() { int d; for (int r = 0; r < 5; ++r) { for (int c = 0; c < 5; ++c) { scanf("%d", &grid[r][c]); } } set<int> ans; for (int r = 0; r < 5; ++r) { for (int c = 0; c < 5; ++c) { set<string> ret = dfs(r, c, 6); // (r, c)から6マスで得られる数セット set<string>::iterator it = ret.begin(); while (it != ret.end()) { ans.insert(atoi((*it).c_str())); ++it; } } } printf("%d\n", ans.size()); }
スーパー遅いんですけど(^^;
id:ororog, id:halwhite教えて!