您的位置:首页 > 其它

hdu 1175 [连连看] dfs搜索

2013-07-15 23:24 375 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1175

题目大意:= = 因为是中文题,就不多说了。  题目对两块棋子能否消除的限制为 两者之间的连线不能转向2次以上,并且不能穿过其他棋子.

个人想法:dfs.如果能满足题目的条件从一块搜索到另一块,那么就输出YES,否则NO。

= =。 但这边不知道为何,如果没有在转向两次以后进行剪枝(接下去就只朝一个方向走)的话,就是超时.

结合网上的题解,进行了剪枝.

剪了枝之后时间一下子就从超时降到了 3700ms.

- -. 只能在这边感叹搜索算法中剪枝的重要性.

以下是ac代码

#include <stdio.h>
#include <string.h>

int map[1010][1010];
char vis[1010][1010];
int m,n;

int tx[] = {0,0,0,-1,1};
int ty[] = {0,1,-1,0,0};

/* 0:原地,1:上,2:下,3:左,4:右 */

int dfs(int s_x,int s_y,int e_x,int e_y,int dir,int change){

if(change==4)
return 0;

if(s_x == e_x && s_y == e_y){
return 1;
}

if(vis[s_x][s_y])
return 0;

int i;
int ex;
int ey;
int ans = 0;

vis[s_x][s_y] = 1;
if(change==3){
ex = s_x + tx[dir];
ey = s_y + ty[dir];
if(ex>=1 && ex<=m && ey>=1 && ey<=n && (map[ex][ey]==0 || ex==e_x && ey==e_y)){
if(dfs(ex,ey,e_x,e_y,dir,change))
return 1;
}
}/*摘自网上的对于 换了2次后的 优化*/
else{
for(i=1;i<=4;i++){
ex = s_x + tx[i];
ey = s_y + ty[i];
if(ex>=1 && ex<=m && ey>=1 && ey<=n && (map[ex][ey]==0 || ex==e_x && ey==e_y)){
if(dir!=i){
if(dfs(ex,ey,e_x,e_y,i,change+1))
return 1;
}
else{
if(dfs(ex,ey,e_x,e_y,i,change))
return 1;
}
}
}
}
vis[s_x][s_y] = 0;/*为了回溯*/
return 0;
}

int main(int argc, char const *argv[])
{
while(scanf("%d %d",&m,&n)!=EOF&&(m||n)){
int i,j;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
scanf("%d",&map[i][j]);

int T;
scanf("%d",&T);
int x1,y1,x2,y2;
while(T--){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
memset(vis,0,sizeof(vis));
if(map[x1][y1]!=map[x2][y2]||(!(map[x1][y1]||map[x2][y2])))
printf("NO\n");
else{
if(dfs(x1,y1,x2,y2,0,0) == 1)
printf("YES\n");
else
printf("NO\n");
}

}
}
return 0;
}


第一篇题解

也是前几道搜索的尝试,第一次体会到剪枝的牛X.

如果有什么问题,欢迎指出,

如果有什么错误,也请看官轻拍.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 搜索 剪枝