| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 897 人关注过本帖
标题:十八期编程比赛的那道搜索题目
只看楼主 加入收藏
ACKing
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-9-4
收藏
 问题点数:0 回复次数:7 
十八期编程比赛的那道搜索题目

找不到原来的帖子了。。。开了一个新贴。
原题链接 http://acm.jlu.edu.cn/joj/showproblem.php?pid=2438
题目意思大概就是从一个格子的左上角走到又下角的最小步数。如果没有其他的条件
这个就是一个很基本的搜索题目,这个题中增加了大小两种怪物,而且同一个格子能
多次经过,令题目的难度增加了不少。
有一个比较好的剪枝就是:纪录着每个格子的当前的最优值,这个最优值包括两个,
一个是经过这个格子的步数,一个是经过这个格子的时候已经杀了小怪兽的数目。
当经过一个 "." 的格子(空格子)的时候,应该判断,当前的步数是否小于这个格子纪录
的步数,或者当前已经杀的小怪兽的数目比当前纪录的小怪兽的数目大。只有这两个条件
之一成立,这一步才值得去走,其中道理大家想一想就明白的了。
有了这个剪枝,注意一点特殊的边界数据,就能解决这个题目了。
Eastsun的想法我都有想过,算法应该没错的。不知道他现在过了没?
在zju有一道比较相似的题目,剪枝的思想也和这个题目差不多
http://acm.zju.edu.cn/show_problem.php?pid=1671


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int inf= 10000000;

char map[10][10];
int d[10][10];
int kill[10][10];
int n,m,k;

int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};

void dfs(int x,int y,int &ans,int sum,int killed)
{
if(map[x][y]=='#')return ;
if(sum>=ans)return ;
if(x==n-1 && y==m-1){
if(map[x][y]!='O')ans=sum;
else if(killed>=k)ans=sum;
return ;
}
int xx,yy,i;
char tmpm=map[x][y];
int tmpd=d[x][y];
int tmpk=kill[x][y];
for(i=0;i<4;i++){
xx=x+dir[i][0];yy=y+dir[i][1];
if(xx>=0 && xx<n && yy>=0 && yy<m){
if(map[x][y]=='o'){
map[x][y]='.';
d[x][y]=sum+1;
kill[x][y]=killed+1;
dfs(xx,yy,ans,sum+1,killed+1);
map[x][y]=tmpm;
d[x][y]=tmpd;
kill[x][y]=tmpk;
}
if(map[x][y]=='O'&&killed>=k){
map[x][y]='.';
d[x][y]=sum+1;
kill[x][y]=killed;
dfs(xx,yy,ans,sum+1,killed);
d[x][y]=tmpd;
kill[x][y]=tmpk;
map[x][y]=tmpm;
}
if(map[x][y]=='.'){
if((d[x][y]>sum+1) || (kill[x][y]<killed)){
d[x][y]=sum+1;
kill[x][y]=killed;
dfs(xx,yy,ans,sum+1,killed);
d[x][y]=tmpd;
kill[x][y]=tmpk;
}
}
}
}
}
int main()
{
int i,j;
while(scanf(\"%d%d%d\",&n,&m,&k)!=EOF)
{
for(i=0;i<n;i++)scanf(\"%s\",map[i]);
for(i=0;i<n;i++)for(j=0;j<m;j++)d[i][j]=inf;
memset(kill,0,sizeof(kill));
int ans=inf;
dfs(0,0,ans,0,0);
if(ans!=inf)printf(\"%d\n\",ans+1);
else printf(\"-1\n\");
}
return 0;
}

搜索更多相关主题的帖子: 格子 搜索 acm 步数 
2007-09-18 21:41
crackerwang
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:833
专家分:0
注 册:2007-2-14
收藏
得分:0 
你总算肯把你思路说出来了....
再不说我也想问你了...
写了几天都没过..

2007-09-18 22:35
crackerwang
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:833
专家分:0
注 册:2007-2-14
收藏
得分:0 
那我的那个3KB两个bfs和eastsun差不多...
难道我的那个想法也没错.
可惜还是没过.
不知道是特殊数据没有考虑到还是根本就是算法是错的.

[此贴子已经被作者于2007-9-18 22:39:53编辑过]


2007-09-18 22:38
ACKing
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-9-4
收藏
得分:0 

其实我比较反对贴代码的。。。。但是我的思路也就是短短几句话,难登大雅之堂。。。

2007-09-18 22:41
crackerwang
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:833
专家分:0
注 册:2007-2-14
收藏
得分:0 
开始你提示我之后我也写了一个不过没有把步数考虑进去.结果RE了.
貌似这个题目有很奇怪的特殊数据.应该TLE的都是WA

2007-09-18 22:43
ACKing
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-9-4
收藏
得分:0 
这个题目数据应该没有那么恐怖。。。毕竟64个格子的搜索理论上怎么都过不去的。。。如果是考你这个理论的负责度的话,那样就没什么意思了。。。这个题的剪枝思想比较好
2007-09-18 22:48
ACKing
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-9-4
收藏
得分:0 
你那个bfs的做法。。。是我开始的写法。。。写了一半发现比较难纪录状态,就改成了深搜了
2007-09-18 22:51
crackerwang
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:833
专家分:0
注 册:2007-2-14
收藏
得分:0 

我以前也做过一个比较类似的题目,也是同一坐标可能经过多次.那个题目也是8*8.结果用64位加set就过了.所以这个题目上来一写就想到那个方法...


2007-09-19 11:49
快速回复:十八期编程比赛的那道搜索题目
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016344 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved