您的位置:首页 > 其它

HDU 2782 The Worm Turns 【dfs深搜】

2018-02-02 00:10 363 查看
传送门

// 题意: 给定一个n*m的矩阵, 有些地方上有石头不能通过, 蠕虫移动的规则是一旦确定了方向, 那么它会向这个方向一直移动, 直到遇到了石头或者墙或者自己曾经吃过的地方, 才能换方向. 问从哪为起点可以经过尽量多的空地, 如果有多解那么输出字典序小的坐标为地点, 并且方向也是以E, N, S, W为优先级.

// 思路: 这道题最好的做法就是dfs, 看一下时限, 发现能试着搜, 所以就写写. 就是一般套路的dfs, 有几个剪枝要注意, 尽量少的调用函数, 以及第一次不能转方向的剪枝, 加上就能过了.

特别注意就是起始点的方向不能转动, 不懂了可以试试不加这个限制会出现什么情况(方向一定是 ‘E’).

AC Code

const int maxn = 625+5;
int cas=1;
int n, m;
int s[maxn][maxn];
int dx[] = {0, 0, -1, 1, 0};  // 题目要求的这四种顺序
int dy[] = {0, 1, 0, 0, -1};
char dd[] = {0, 'E', 'N', 'S', 'W'};
bool vis[maxn][maxn];
int maxfood;
int sx, sy, sd, ex, ey, ed;
void dfs(int nowx, int nowy, int dir, int food) {
if (food > maxfood) {
maxfood = food;
ex = sx; ey = sy; ed = sd;
}
int xx = nowx + dx[dir] ; int yy = nowy + dy[dir];
if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && !vis[xx][yy] && !s[xx][yy]) {
vis[xx][yy] = 1;
dfs(xx, yy, dir, food+1);
vis[xx][yy] = 0;
}
else {
if (food == 1) return ; // 第一步不能换方向, 必须搜下去, 因为ans里面需要确定这个方向.
for (int i = 1 ; i <= 4 ; i ++) {
if (i == dir) continue;
xx = nowx + dx[i];
yy = nowy + dy[i];
if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && !vis[xx][yy] && !s[xx][yy]) {
vis[xx][yy] = 1;
dfs(xx, yy, i, food+1);
vis[xx][yy] = 0;
}
}
}
}
void solve()
{
while(~scanf("%d%d",&n, &m)) {
if (n + m == 0) break;
int k; Fill(s, 0);
scanf("%d", &k);
for(int i = 1 ; i <= k ; i ++) {
int x, y;
scanf("%d%d", &x, &y);
x++; y++;
s[x][y] = -1;
}
maxfood = -1;
for(int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= m ; j ++) {
for (int k = 1 ; k <= 4 ; k ++) {
if (!s[i][j]) {
sx = i; sy = j; sd = k;
vis[i][j] = 1;
dfs(i, j, k, 1);
vis[i][j] = 0;
}
}
}
}
printf("Case %d: ", cas++);
ex--; ey--;
printf("%d %d %d %c\n", maxfood, ex, ey, dd[ed]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: