假设当前已经到达(x,y),用bfs判断一下还可以到达的点有maxd个,如果maxd加上当前已经经过的长度小于当前答案的长度就退出,如果相同,就将bfs搜索到的点从大到小排序,如果连最大序列都无法大于当前答案,就直接退出,否则继续搜索。
但是这题时间要求极高,不可以同时搜索同时更新答案,必须直到完成一种搜索(到达边界)才能更新答案,否则必定超时。
AC代码:
#include
#include
#include
#include
using namespace std;
const int maxn = 30 + 5;
char G[maxn][maxn];
int vis[maxn][maxn], d[maxn][maxn];
int n, m;
int ans[maxn], len; //答案以及答案的长度
int a[maxn];
struct node{
int x, y;
node(){
}
node(int x, int y):x(x), y(y){
}
};
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
int bfs(int x, int y, int cur){ //从cur开始保存
int c = cur;
memcpy(d, vis, sizeof(vis));
queueq;
q.push(node(x, y));
d[x][y] = 1;
while(!q.empty()){
node pos = q.front();
q.pop();
x = pos.x, y = pos.y;
for(int i = 0; i < 4; ++i){
int px = x + dx[i], py = y + dy[i];
if(px < 0 || px >= n || py < 0 || py >= m) continue;
if(G[px][py] == '#' || d[px][py]) continue;
d[px][py] = 1;
a[c++] = G[px][py] - '0';
q.push(node(px, py));
}
}
return c;
}
bool cmp(int a, int b){
return a > b;
}
void dfs(int x, int y, int cur){
int h = bfs(x, y, cur);
if(h == cur) { //边界
int flag = 0;
if(cur < len) return;
else if(cur > len) flag = 1;
else for(int i = 0; i < len; ++i){
if(a[i] < ans[i]) return;
else if(a[i] > ans[i]) {
flag = 1;
break;
}
}
if(flag) {
len = cur;
for(int i = 0; i < len; ++i) ans[i] = a[i]; //update
}
return;
}
if(h < len) return;
else if(h == len){
sort(a + cur, a + h, cmp);
int flag = 0;
for(int i = 0; i < len; ++i) {
if(a[i] < ans[i]) return;
else if(a[i] > ans[i]) {
flag = 1;
break;
}
}
if(!flag) return;
}
for(int i = 0; i < 4; ++i){
int px = x + dx[i], py = y + dy[i];
if(px < 0 || px >= n || py < 0 || py >= m) continue;
if(G[px][py] == '#' || vis[px][py]) continue;
a[cur] = G[px][py] - '0';
vis[px][py] = 1;
dfs(px, py, cur + 1);
vis[px][py] = 0;
}
}
int main(){
while(scanf("%d%d", &n, &m) == 2 && n){
memset(ans, 0, sizeof(ans));
len = 0;
for(int i = 0; i < n; ++i) scanf("%s", G[i]);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j) {
if(G[i][j] == '#') continue;
memset(vis, 0, sizeof(vis));
a[0] = G[i][j] - '0';
vis[i][j] = 1;
dfs(i, j, 1);
vis[i][j] = 0;
}
for(int i = 0; i < len; ++i){
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}
还有一种dfs代码,思路同上
#include
#include
#include
#include
using namespace std;
const int maxn = 30 + 5;
char G[maxn][maxn];
int vis[maxn][maxn], d[maxn][maxn];
int n, m;
int ans[maxn], len; //答案以及答案的长度
int a[maxn];
struct node{
int x, y;
node(){
}
node(int x, int y):x(x), y(y){
}
};
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
bool cmp(int a, int b){
return a > b;
}
int bfs(int x, int y, int cur){
int c = cur;
memcpy(d, vis, sizeof(vis));
queueq;
q.push(node(x, y));
d[x][y] = 1;
while(!q.empty()){
node pos = q.front();
q.pop();
x = pos.x, y = pos.y;
for(int i = 0; i < 4; ++i){
int px = x + dx[i], py = y + dy[i];
if(px < 0 || px >= n || py < 0 || py >= m) continue;
if(G[px][py] == '#' || d[px][py]) continue;
d[px][py] = 1;
a[c++] = G[px][py] - '0';
q.push(node(px, py));
}
}
return c;
}
void dfs(int x, int y, int cur){
a[cur++] = G[x][y] - '0';
int h = bfs(x, y, cur);
if(h == cur) { //边界
int flag = 0;
if(cur < len) return;
else if(cur > len) flag = 1;
else for(int i = 0; i < len; ++i){
if(a[i] < ans[i]) return;
else if(a[i] > ans[i]) {
flag = 1;
break;
}
}
if(flag) {
len = cur;
for(int i = 0; i < len; ++i) ans[i] = a[i]; //update
}
return;
}
if(h < len) return;
else if(h == len){
sort(a + cur, a + h, cmp);
int flag = 0;
for(int i = 0; i < len; ++i) {
if(a[i] < ans[i]) return;
else if(a[i] > ans[i]) {
flag = 1;
break;
}
}
if(!flag) return;
}
vis[x][y] = 1;
for(int i = 0; i < 4; ++i){
int px = x + dx[i], py = y + dy[i];
if(px < 0 || px >= n || py < 0 || py >= m) continue;
if(G[px][py] == '#' || vis[px][py]) continue;
dfs(px, py, cur);
}
vis[x][y] = 0;
}
int main(){
while(scanf("%d%d", &n, &m) == 2 && n){
memset(ans, 0, sizeof(ans));
len = 0;
for(int i = 0; i < n; ++i) scanf("%s", G[i]);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j) {
if(G[i][j] == '#') continue;
memset(vis, 0, sizeof(vis));
dfs(i, j, 0);
}
for(int i = 0; i < len; ++i){
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}
如有不当之处欢迎指出!