此题大意:给定一个矩阵,有些地方有数字,有些地方不能走,数字只包含1--9,现在问,可以从任意节点出发,将路径上的所有数字连在一起可以组成的最大的数是多少。
数据范围为 行数*列数 <30且行数大于 行数和列数都小于15 。
此题的第一眼想法就是直接dfs
但是 时间只有1s,直接dfs肯定会超时。
然后就是剪枝
剪枝方法:1.到达一个节点后对这个节点进行bfs,获得这个节点能够到达的节点数(num),当然在当前dfs路径上的节点 不能算在内。
然后就是比较已经获得答案长度anslen 与 num和当前路径的长度len之间的关系。 如果: anslen > num + d 那么没必要在对当前节点dfs了,return。
如果anslen==num +d ,就要知道bfs经历的所有节点然后从大到小排序,然后和当前路径连接起来,与ans比较。
2.如果当前起始节点搜索道德长度等于最长可能的长度,那么其它节点就不在进行dfs了 。(先对节点排序了)
//
// main.cpp
// uva 11882 - Biggest Number
//
// Created by XD on 15/8/5.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
struct node
{
int x ,y ;
int key ;
bool operator < (const node &n ) const{
return key > n.key ;
} ;
};
set<node> g_set[31][31] ;
node temp[31] ;
int ansmax , maxlen ;
int g[30][30] ;
int visd[30][30] ;
int visb[30][30] ;
int ans[31] ;
int path[31] ;
int dir[4][2]={
{0,1},{0,-1} ,{-1,0},{1,0}
} ;
set<int > s ;
int row , colum ;
bool overMap(int x ,int y )
{
if (x < 0|| y<0||x >= row||y>=colum) {
return true ;
}
return false ;
}
int _node[35] ;
int bfs(int x , int y )
{
// memset(visb, 0,sizeof(visd)) ;
_node[0] = 1 ;
queue<node> que ;
node f,next ;
f.x = x ;f.y = y; f.key= g[x][y] ;
visb[x][y] = 1 ;
int num = 0 ;
que.push(f) ;
while (!que.empty()) {
f = que.front() ; que.pop() ;
for (int i = 0 ; i < 4; i++) {
int tx = f.x + dir[i][0] ;
int ty = f.y + dir[i][1] ;
if (!overMap(tx, ty)&& !visb[tx][ty]&&!visd[tx][ty] && g[tx][ty]!= 0) {
visb[tx][ty] = 1 ;
next.x = tx ;next.y = ty ;
next.key = g[tx][ty] ;
que.push(next) ;
_node[_node[0]++] = next.key ;
num++ ;
}
}
}
return num ;
}
void dfs(int x , int y,int d )
{
memcpy(visb, visd,sizeof(visd)) ;
int num = bfs(x,y) ;
if (ansmax > num +d ) {
return ;
}
else if (ansmax == num + d && num!=0)
{
int flag = 0;
sort(_node+1 , _node + _node[0] ) ;
for (int i = 1 ; i <= d; i++) {
if(ans[i] > path[i])
{
return ;
}
else if(ans[i] < path[i]){
flag = 1;
break ;
}
}
if (!flag) {
int j = _node[0]-1 ;
for (int i=d+1; i<=ansmax; i++) {
if (ans[i] > _node[j]) {
return ;
}
else if(ans[i] < _node[j]){
flag=1 ;
break ;
}
j-- ;
}
}
if (!flag) {
return ;
}
}
for (int i = 0; i < 4 ; i++)
{
int tx = x +dir[i][0] ; int ty = y + dir[i][1] ;
if (!overMap(tx, ty)&& visd[tx][ty]==0 && g[tx][ty] != 0 ) {
visd[tx][ty] =1 ;
path[d+1] = g[tx][ty] ;
dfs(tx, ty, d + 1) ;
visd[tx][ty] = 0 ;
}
}
if (ansmax <=d) {
if(ansmax < d ){memcpy(ans,path,sizeof(path)) ;
ansmax = d;}
else{
for (int i = 1; i <=ansmax; i++) {
if (ans[i] < path[i]) {
memcpy(ans, path, sizeof(int) * (ansmax+1)) ;
break ;
}
else if (ans[i] > path[i])
{
return ;
}
}
}
}
}
int main() {
char s[32] ;
while(scanf(" %d%d" ,&row,&colum)==2 && row + colum!=0)
{
int t = 0 ;
for (int i = 0; i < row
; i++) {
scanf(" %s" , s) ;
for (int j = 0; j < colum; j++) {
if (s[j] == '#') {
g[i][j] = 0 ;
}
else{
temp[t].x = i ;temp[t].y = j ;
temp[t++].key = s[j] - 48 ;
g[i][j] = s[j]-48;
}
}
}
sort(temp, temp + t) ;
maxlen = t ;
ansmax = 0 ;
for (int i= 0; i<t; i++) {
memset(visd, 0, sizeof(visd)) ;
path[1] = temp[i].key ;
visd[temp[i].x][temp[i].y] = 1 ;
dfs(temp[i].x, temp[i].y,1) ;
if(ansmax == t && i <t && temp[i+1].key<temp[i].key)
{
break ;
}
}
for (int i = 1; i < ansmax+1; i++) {
printf("%d" ,ans[i]) ;
}
printf("\n") ;
}
return 0;
}