diff --git "a/docs/views/dev/2020-11-22-\351\242\230\350\247\243POJ3050\357\274\210DFS\357\274\211.md" "b/docs/views/dev/2020-11-22-\351\242\230\350\247\243POJ3050\357\274\210DFS\357\274\211.md" new file mode 100644 index 00000000..bc833636 --- /dev/null +++ "b/docs/views/dev/2020-11-22-\351\242\230\350\247\243POJ3050\357\274\210DFS\357\274\211.md" @@ -0,0 +1,79 @@ +--- +layout: post +title: 题解POJ3050(DFS) +date: 2020-11-22 +author: GuChongAn +tags: + - 后端 + - 算法 + - POJ +categories: + - 开发部 +--- +# 01、题目描述 + +今天我们要解决的是一道深搜题——POJ3050 Hopscotch,今天要用到的知识有,**深度优先搜索(DFS)** 以及 **C++< set >库**(set中**不允许有相同元素**)的一些使用。 + +题目链接: [POJ3050 Hopscotch](http://poj.org/problem?id=3050). +题目描述:输入一个5x5的整数矩阵,从**任意数字**开始,可以向前后左右四个方向运动,运动5次后,得到一个**由6个数字组成**的序列,问共有多少种**不同**的序列。 +**示例输入:** + +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(共有15种不同的序列,111111, 111112, 111121, 111211, 111212, 112111, 112121, 121111, 121112, 121211, 121212, 211111, 211121, 212111, 212121) + +# 02、解题思路 + + 看完题目后,很自然的想到,如果能**算出所有的序列**,然后**删去重复的序列**,就可以得到答案,同时因为本题数据量不大,所以可以不作其他处理。通过**DFS深搜**的方法,从一个位置开始,运动至得到一个6个数的序列,然后返回上一步(既只有5个数的状态),再向另外的方向运动,又返回,又运动,如此反复就可以得到所有的序列。然后删去重复的序列,只需要把DFS搜索出的所有序列**insert到set中去**,就可以删去重复序列(set本身不允许存在相同的元素),最后再 **set.size()** 就可以得到答案。 + +# 03、题解代码 + +```C++ +#include +#include +using namespace std; + +int map[6][6]; +set ans; +int dx[4] = {-1, 1, 0, 0}; +int dy[4] = {0, 0, 1, -1}; + +void dfs(int x, int y, int step, int temp) { + if(step == 5) { + ans.insert(temp); //把序列加入set + return ; + } + + for(int i = 0; i < 4; i++) { + int nx = dx[i] + x; + int ny = dy[i] + y; + if(nx>=0 && nx<5 && ny>=0 && ny<5){ + dfs(nx, ny, step+1, temp*10+map[nx][ny]);//temp*10相当于左移一位原位补零 + } + } +} + +int main() { +//初始化 + for(int i = 0; i < 5; i++) + for(int j = 0; j < 5; j++) + cin >> map[i][j]; + +//dfs + for(int i = 0; i < 5; i++) + for(int j = 0; j < 5; j++) + dfs(i, j, 0, map[i][j]); + + cout << ans.size() << endl; + + return 0; +} +```