您的位置:首页 > 产品设计 > UI/UE

UESTC 1086 邱老师降临小行星 (记忆化搜索)

2016-05-09 20:44 411 查看
题目链接:http://acm.uestc.edu.cn/#/problem/show/1086

直接搜会超时…显然,我居然还试了一发….

所以要用记忆化搜索。

每一个点有四种到达方式,上,右,下,左,每种又分为在这一个点下一步应该往左走还是往右走。所以一个点共有八种状态,开数组,记忆每一个点在每一种状态能走多远距离,就可以避免重复搜索。

参考博客:/article/8729357.html 感谢!

方向的数组dx、dy的意义:

dx[0]和dx[4]表示面向上时向右走和向左走。

dx[1]和dx[5]表示面向右时向右走和向左走。

dx[2]和dx[6]表示面向下时向右走和向左走。

dx[3]和dx[7]表示面向左时向右走和向左走。

而0 - 7则表示八种状态。

dfs的参数s即表示状态号(0 - 7),(s + 4)% 8 即可得到下一步的状态。

这题有个坑点,我不太懂为什么,读入地图的时候如果按照字符一个一个地读入,并且用getchar读回车的话会直接WA,更奇怪的是在vj上的样例这么读过不了,但是OJ上的样例却能过….难道它们不一样吗….

而改成用scanf(“%s”, str)每次读一行就没问题了,这是因为数据不规范吗?不是很懂…..

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1010;
int N, M;
char map[maxn][maxn];
int sta[maxn][maxn][8];
int dx[8] = {0, 1,  0, -1, -1, 0, 1,  0};
int dy[8] = {1, 0, -1,  0,  0, 1, 0, -1};
int dfs(int x, int y, int s) {
if(x < 1 || x > N || y < 1 || y > M) return 0;
if(map[x][y] == '0') return sta[x][y][s] = 0;
if(sta[x][y][s] != -1) return sta[x][y][s];
return sta[x][y][s] = 1 + dfs(x + dx[s], y + dy[s], (s + 4) % 8);  //(s + 4) % 8为下一步的状态
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &N, &M);
getchar();
int i, j, k;
char str[maxn];
for(i = 1; i <= N; i++) {
scanf("%s", str);
for(j = 1, k = 0; j <= M; j++, k++) {
map[i][j] = str[k];
}
}
memset(sta, -1, sizeof(sta));  //初始化为-1
int ans = 0;
for(i = 1; i <= N; i++) {
for(j = 1; j <= M; j++) {
if(map[i][j] == '1') {
int res = 1;
res += dfs(i - 1, j, 0); //四个方向分别搜索,上右下左
res += dfs(i, j + 1, 1);
res += dfs(i + 1, j, 2);
res += dfs(i, j - 1, 3);
if(res > ans) ans = res;
}
}
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: