当前位置: 代码迷 >> 综合 >> 11882 - Biggest Number ( 深搜 )
  详细解决方案

11882 - Biggest Number ( 深搜 )

热度:51   发布时间:2023-12-26 13:23:16.0

题目链接:传送门

思路: 以每个数字为起点去深搜,取在深搜过程中搜到的最大的 数。

注意, 如果只用蛮力去深搜会超时,所以需要剪枝。

剪枝需要用到广搜,就是你用深搜搜到某个点之后,先用广搜去计算 这个点继续深搜还能遍历所有的数字个数 a,假设现在Biggest Number 长度为 b, 搜到这个点已经深搜 的数的长度 c:

两种情况:

 1.  a+c < b     那么这个点就不用再往下搜了,以为就把之后所有的点全搜了,也不会比现在的 Biggest Number 大,继续搜下去就傻乎乎的了。

2. a+c == b     那么需要需要去从当前点深搜可以生成最大的数 《==》 就是将广搜到的a个数 降序 排列, 接在 c 个数后面, 这样生成了 当前点深搜可以生成最大的数 ,如果大于 现在的 Biggest Number, 那么就可以继续深搜下去。

参考代码:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;const int N = 35;int road[4][2] = {-1,0,1,0,0,-1,0,1};char ans[N*N];
char a[N][N];
int vis[N][N];
int mark[N][N];
char v[N*N];
int n, m;
bool cmp(char A, char B)
{return B < A;
}
typedef struct point
{int x, y;
} Point;
bool judge(int x, int y)
{// 判断点 (x,y)是否在迷宫中if(x < 0 || x >= n || y < 0 || y >= m)return false;return true;
}
queue <Point> Q;
int bfs(int i,int j)
{// 广搜去计算 这个点(i,j)继续深搜还能遍历所有的数字个数 ans// 字符串 v 中存储 广搜到的 ans 个数int ans = 0;memset(mark, 0, sizeof(mark));while(!Q.empty()) Q.pop();Point now, tem;now.x = i, now.y = j;Q.push( now );mark[now.x][now.y] = 1;while(!Q.empty()){now = Q.front();Q.pop();for(int d=0; d<4; d++){tem.x = now.x + road[d][0];tem.y = now.y + road[d][1];if(!judge(tem.x, tem.y) || vis[tem.x][tem.y] ||a[tem.x][tem.y] == '#' || mark[tem.x][tem.y])continue;v[ans++] = a[tem.x][tem.y];mark[tem.x][tem.y] = 1;Q.push(tem);}}return ans;
}
void dfs(int x, int y, char now[], int k)
{// 深搜去 寻找 Biggest Numberint len = strlen(ans);if(len < k){strcpy(ans, now);}else if(len == k){for(int i=0; i<len; i++){if(now[i] > ans[i]){strcpy(ans, now);break;}if(ans[i] > now[i])break;}}else{int temp = bfs(x, y);if(temp+k < len)// 就把之后所有的点全搜了,也不会比现在的 Biggest Number 大return;if(temp+k == len){//a+c == b     那么需要需要去从当前点深搜可以生成最大的数// 就是将广搜到的a个数 降序 排列, 接在 c 个数后面, 这样生成了 当前点深搜可以生成最大的数 ,// 如果大于 现在的 Biggest Number, 那么就可以继续深搜下去。char temp1[N*N];sort(v, v+temp, cmp);v[temp] = '\0';strcpy(temp1, now);strcat(temp1, v);for(int i=0; i<len; i++){if(temp1[i] < ans[i]){return ;}if(temp1[i] > ans[i])break;}}}for(int i=0; i<4; i++){int temx, temy;temx = x+road[i][0];temy = y+road[i][1];if(!judge(temx, temy) || a[temx][temy] == '#' || vis[temx][temy])continue;vis[temx][temy] = 1;now[k] = a[temx][temy];dfs(temx, temy, now, k+1);now[k] = '\0';vis[temx][temy] = 0;}
}int main()
{while(scanf("%d %d",&n, &m)){if(n == 0 && m == 0)break;for(int i=0; i<n; i++){scanf("%s", a[i]);}memset(vis, 0, sizeof(vis));ans[0] = 0;char now[N*N];for(int i=0; i<n; i++){for(int j=0; j<m; j++){// 以每个位数字的点为起点去 深搜if(a[i][j] == '#')continue;memset(vis, 0, sizeof(vis));memset(now, 0, sizeof(now));vis[i][j] = 1;now[0] = a[i][j];dfs(i, j, now, 1);}}cout << ans << endl;}return 0;
}

 

  相关解决方案