Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions docs/views/dev/2020-11-22-题解POJ3050(DFS).md
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <set>
using namespace std;

int map[6][6];
set<int> 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;
}
```