问题描述
母牛以非传统方式玩孩子的跳房子游戏。母牛没有跳入的一组线性数字框,而是创建了一个与x和y轴平行的5x5直线数字网格。
然后,他们熟练地跳到网格中的任何数字,然后向前,向后,向右或向左 跳到网格中的另一个数字。他们再次跳(相同的规则)到一个数字(可能是一个已经访问过的数字)。
共有5个网格内跃点,它们的跃点会创建一个六位整数(可能具有前导零,如000201)。
确定可以通过这种方式创建的不同整数的数量的计数。
样例输入(5*5)
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 2 1
1 1 1 1 1
样例输出
15(可以构造111111、111112、111121、111211、111212、112111、112121、121111、121112、121211、121212、211111、211121、212111和212121。没有其他值是可能的。)
问题解释
题目问题规模小,直接暴力加深度优先搜索。因为题目没有说从哪里开始跳,所以每个格子都得试一试(暴力)。接着就是可以上下左右跳动(即dfs)。总共跳六次。
代码使用了set集合,这是因为需要避免搜索过程中出现重复的现象,然后输入set大小。(今天刚学,现学现用 嘻嘻~)
#include<iostream>
#include<set>
using namespace std;
int map[5][5] =
{
{1,1,1,1,1},
{1,1,1,1,1},
{1,1,1,1,1},
{1,1,1,2,1},
{1,1,1,1,1}
};
int dx[4] = { 1, -1, 0, 0 };
int dy[4] = { 0, 0, 1, -1 };
set<int> s;
//************************************
// Method: 暴力+dfs
// FullName: 穷竭搜索+深度优先搜索
// Access: public
// Returns: void
// Idea: 六步迷宫问题
//************************************
void dfs(int x, int y, int (*map)[5], int value, int step)
{
if (step == 5)
{
s.insert(value);
return;
}
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if (0 <= nx && nx < 5 && 0 <= ny && ny < 5)
{
step++;
dfs(nx, ny, map, value * 10 + map[nx][ny], step);
step--;
}
}
}
void solve()
{
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
dfs(i, j, map, map[i][j], 0);
}
}
cout << s.size() << endl;
}
///////////////////////SubMain//////////////////////
int main()
{
solve();
return 0;
}
///////////////////////SubEnd//////////////////////