C++深度优先搜素

深度优先搜索特点:穷举所有情况、全排列==完全图、顶点数最好小于11、需要哈希表和栈的数据结构基础。

算法描述,第一步,初始化数据结构,全排列在计算过程中,需要利用一个哈希表visited和一个栈stack来记录当前访问过的节点。其中哈希表是为了快速查找某个节点是否被访问,并且执行插入,栈是为了记录顶点的访问顺序。

第二步,顶点访问,依次访问所有顶点,如果发现这个顶点没有在哈希表中,则把它插入哈希表,并且把这个顶点入栈。这样一来,哈希表和栈中,存储的就是本次遍历中存储的点。

第三步,递归调用,利用递归进行调用自身,继续访问下一个节点。

第四步,当本次访问的顶点数等于总顶点数的时候,栈中的元素就代表一个排列,把排列进行输出或者做其他相应的处理。

第五步,回溯,当没有任何顶点需要访问的时候,进行回溯。回溯就是将栈顶元素出栈,并且将这个元素从哈希表中移除

代码分析,

第一步,初始化数据结构

function initData(visited, stack)

visited.clear()

stack.clear()

第二步,框架代码

function dfs(depth, maxDepth)

if depth == maxDepth

print(stack)

return

for i -> (0, maxDepth - 1)

if i not in visited

visited.add(i)

stack.push(i)

dfs(depth+1, maxDepth)

visited.remove(i)

stack.pop()

这个算法时间复杂度为n的阶乘

代码练习 1 对应蓝桥云课 排列序数 代码见下

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
using namespace std;

#define maxn 10
string str;

int ans;
int visited[maxn];
int stack[maxn];
int cnt;
string sorted;
void dfs(int depth, int maxDepth){
  if(depth == maxDepth){
    int i;
    for(i=0; i<maxDepth; ++i){
      int idx = stack[i];
      if(sorted[idx] != str[i]){
        break;
      }
    }
    if(i == maxDepth){
      ans = cnt;
    }
    ++cnt;
    return;
  }
  for(int i=0; i<maxDepth; ++i){
    if(!visited[i]){
      visited[i] = 1;
      stack[depth] = i;
      dfs(depth+1, maxDepth);
      visited[i] = 0;
    }
  }
}
int main()
{
  cin >> str;
  sorted = str;
  sort(sorted.begin(), sorted.end());
  memset(visited, 0, sizeof(visited));
  cnt = 0;
  dfs(0, str.size());
  cout << ans << endl;
  // 请在此输入您的代码
  return 0;
}

代码练习 2 对应蓝桥云课 十位数宝藏代码 代码见下

cpp 复制代码
#include <iostream>
using namespace std;

#define maxn 10

int visited[maxn];
int stack[maxn];

long long Min = (long long)9876543210;
long long Max = 0;

void dfs(int depth, int maxDepth, long long ans){
  if(depth == maxDepth){
    if(ans % 11 == 0){
      if(ans < Min) Min = ans;
      if(ans > Max) Max = ans;
    }
    return;
  }
  if(depth == 1){
    if(ans == 0){
      return;
    }
  }
  for(int i=0; i<maxDepth; ++i){
    if(!visited[i]){
      visited[i] = 1;
      stack[depth] = i;
      dfs(depth+1, maxDepth, ans*10 + i);
      visited[i] = 0;
    }
  }
}

int main()
{
  dfs(0, 10, 0);
  cout << Max - Min << endl;

  // 请在此输入您的代码
  return 0;
}

代码练习3 对应蓝桥云课带分数, 代码见下

cpp 复制代码
#include <iostream>
using namespace std;

// #define maxn 10

// int visited[maxn];
// int stack[maxn];

// void dfs(int depth, int maxDepth){
//   if(depth == maxDepth){
//      // stack存储了[0, maxDepth-1]的全排列
//     return;
//   }
//   for(int i=0; i<maxDepth; ++i){
//     if(!visited[i]){
//       visited[i] = 1;
//       stack[depth] = i;
//       dfs(depth+1, maxDepth);
//       visited[i] = 0;
//     }
//   }
// }

#define maxn 10
int N;
int ans;
int visited[maxn];

int pow10[maxn] = {
  1,
  10,
  100,
  1000,
  10000,
  100000,
  1000000,
  10000000,
  100000000,
  1000000000
};
int cnt(int sum){
  int ans = 0;
  for(int i = 8; i >= 0; --i){
    int x = sum / pow10[i];
    if(N <= x){
      break;
    }
    int y = N - x;
    int z = sum % pow10[i];
    for(int j = 1 ; ; ++j){
      int fm = z % pow10[j];
      int fz = z / pow10[j];
      if(fz < fm){
        break;
      }
      if(fz % fm == 0){
        if(fz / fm == y){
          ++ans;
        }
      }
    }
  }
  return ans;
}

void dfs(int depth, int maxDepth, int sum){
  if(depth == maxDepth){
    ans += cnt(sum);
     // stack存储了[0, maxDepth-1]的全排列
    return;
  }
  for(int i=0; i<maxDepth; ++i){
    if(!visited[i]){
      visited[i] = 1;
      dfs(depth+1, maxDepth, sum*10+(i+1));
      visited[i] = 0;
    }
  }
}

int main()
{
  cin >> N;
  dfs(0, 9, 0);
  cout << ans << endl;

  // 请在此输入您的代码
  return 0;
}
相关推荐
野犬寒鸦30 分钟前
从零起步学习并发编程 || 第四章:synchronized底层源码级讲解及项目实战应用案例
java·服务器·开发语言·jvm·后端·学习·面试
£漫步 云端彡35 分钟前
Golang学习历程【第十一篇 接口(interface)】
开发语言·学习·golang
virus59458 小时前
悟空CRM mybatis-3.5.3-mapper.dtd错误解决方案
java·开发语言·mybatis
一匹电信狗9 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
初次见面我叫泰隆9 小时前
Qt——3、常用控件
开发语言·qt·客户端
Queenie_Charlie9 小时前
小陶的疑惑2
数据结构·c++·树状数组
无小道10 小时前
Qt——QWidget
开发语言·qt
时艰.10 小时前
Java 并发编程之 CAS 与 Atomic 原子操作类
java·开发语言
梵刹古音10 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
梵刹古音11 小时前
【C语言】 结构化编程与选择结构
c语言·开发语言·嵌入式