Curling 2.0
一道DFS题目。类似于回溯求解01背包问题,使用BFS的话可能会有点问题,因为在每个石块滚动的时候会是的盘面的状态发生变化,用BFS的话,很容易出错。用DFS加小剪枝,第一当搜索已经过10的时候可以不用再继续搜索下去了。当当前的搜索的值已经超过最优解的时候也是不需要继续搜的。这个题比较麻烦的就是在每次移动的时候是有静止到静止,然后需要算出移动后的位置。然后就是对于可行路径的判断。63ms过
一道DFS题目。类似于回溯求解01背包问题,使用BFS的话可能会有点问题,因为在每个石块滚动的时候会是的盘面的状态发生变化,用BFS的话,很容易出错。用DFS加小剪枝,第一当搜索已经过10的时候可以不用再继续搜索下去了。当当前的搜索的值已经超过最优解的时候也是不需要继续搜的。这个题比较麻烦的就是在每次移动的时候是有静止到静止,然后需要算出移动后的位置。然后就是对于可行路径的判断。63ms过
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std ;
#define MAXN 25
int map[MAXN][MAXN] ;
int row ;//行
int col ;//列
int sx ;
int sy ;
int ex ;
int ey ;
int best;//最少的步骤
int dir[4][2] = {{1 , 0 } , {-1 , 0} , {0 , 1} , {0 , -1}} ;
struct Node{
int x ;
int y ;
};
Node reachPoint(int x , int y , int d){
Node node ;
while(1){
x = x + dir[d][0] ;
y = y + dir[d][1] ;
//越界
if(x <= 0 || x > row || y <= 0 || y > col){
break ;
}
//到达终点或者遇到阻隔
if(map[x][y]==1){
x = x - dir[d][0] ;
y = y - dir[d][1] ;
break ;
}
if(map[x][y]==3){
break ;
}
}
node.x = x ;
node.y = y ;
return node ;
}
bool check(int x ,int y ,int i){
x = x + dir[i][0] ;
y = y + dir[i][1] ;
//如果下一个要走的点越界。不合法
if(x <= 0 || x > row || y <= 0 || y > col){
return 0 ;
}
//不合法
if(map[x][y]==1){
return 0 ;
}
return 1 ;
}
void dfs(int ax , int ay , int bx , int by , int cr){
if(ax==bx && ay==by){
if(best > cr || best == -1){
best = cr ;
}
return ;
}
//如果超过10必定得不到最优解
if(cr >= 10)
return ;
//如果当前的值已经大于best值,不可能得到最优解
if(best >= 0 && best < cr)
return ;
for(int i = 0 ; i < 4 ; i ++){
//先检查下一个点是否合法,如果不合法
if(!check(ax , ay , i)){
continue ;
}
//获得移动后到达的点
Node node = reachPoint(ax , ay , i) ;
int x = node.x ;
int y = node.y ;
//越界
if( x <= 0 || y <= 0 || x > row || y > col){
continue ;
}
if(x != bx || y != by){
if(x + dir[i][0] > 0 && x + dir[i][0] <= row){
if(y + dir[i][1] > 0 && y + dir[i][1] <= col){
map[x + dir[i][0] ][ y + dir[i][1] ] = 0 ;
}
}
}
dfs(x , y , bx , by , cr + 1) ;
if(x != bx || y != by){
if(x + dir[i][0] > 0 && x + dir[i][0] <= row){
if(y + dir[i][1] > 0 && y + dir[i][1] <= col){
map[x + dir[i][0] ][ y + dir[i][1] ] = 1 ;
}
}
}
}
return ;
}
int main(){
while(scanf("%d %d" , &col , &row) != EOF && row && col ){
memset(map , 0 , sizeof(map)) ;
for(int i = 1 ; i <= row ; i ++){
for(int j = 1 ; j <= col ;j ++){
scanf("%d" , &map[i][j]) ;
if(map[i][j] == 2){
sx = i ;
sy = j ;
}
if(map[i][j] == 3){
ex = i ;
ey = j ;
}
}
}
best = -1 ;
dfs(sx , sy , ex, ey , 0) ;
best = best > 10 ? -1 : best ;
printf("%d\n" , best) ;
}
return 0 ;
}
本文介绍了一个基于DFS算法的Curling2.0问题解决方案,该问题涉及石块滚动策略以达到目标位置。文章详细描述了如何通过深度优先搜索(DFS)结合剪枝策略来解决这个问题,并提供了完整的C++实现代码。
1047

被折叠的 条评论
为什么被折叠?



