11882 - Biggest Number

Topic link: Portal

Ideas: Use each number as a starting point to search deeply , and take the largest number found in the process of deep search.

Note that if you only use brute force to search deeply, it will time out, so you need to prune.

Pruning needs to use wide search, that is, after you use deep search to find a certain point, first use wide search to calculate this point and continue deep search to traverse all the number of numbers a . Assuming that the length of Biggest Number is now b , search The length c of the number that has been deeply searched up to this point :

Two cases:

 1. If  a+c < b      , then this point does not need to be searched further. I thought that if I searched all the subsequent points, it would not be larger than the current Biggest Number. It would be silly to continue searching.

2. a+c == b      , then you need to search deeply from the current point to generate the largest number "==" is to sort the number of a's found in the wide search in descending order, and then follow the number of c, thus generating the  current point The deep search can generate the largest number, if it is larger than  the current Biggest Number, then the deep search can be continued.

Reference Code:

#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) {
    // Determine if point (x, y) is in the maze
	if(x < 0 || x >= n || y < 0 || y >= m)
	     return false;
	return true;
}
queue <Point> Q;
int bfs(int i,int j) {
    // Wide search to calculate this point (i, j) and continue to search deeply and traverse all the numbers ans
    // The number of ans found by the wide search is stored in the string v
    int years = 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) {
    // Deep search to find Biggest Number
	int 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)
		// Search all the points after that, and it will not be larger than the current Biggest Number
            return;
        if(temp+k == len) {
        //a+c == b Then you need to search deeply from the current point to generate the largest number
        // It is to arrange the number of a's found in the wide search in descending order, followed by the number of c, so that the current point deep search can generate the largest number,
        // If it is greater than the current Biggest Number, then you can continue to search further.
            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));

		years[0] = 0;
		char now[N*N];

		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
                // Start from the point of each digit to search deeply
				if(a[i][j] == '#')
				  continue;

				memset(vis, 0, sizeof(vis));
				memset(now, 0, sizeof(now));

				show [i] [j] = 1;
				now[0] = a[i][j];
				dfs(i, j, now, 1);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326074434&siteId=291194637