网址:
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0558
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=108221#problem/E
题意:
在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪。有一只老鼠准备从出发点吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。
老鼠从当前格到上下左右相邻的无障碍物的格需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时。
输入:第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞, 1-N代表硬度为1-N的奶酪的工厂。输出最少用时。
题意翻译参考自 http://bbs.byr.cn/#!article/ACM_ICPC/73337?au=Milrivel
因为给出的数字是连续的,初始的值是1,只能吃比自己体力小的奶酪,到达奶酪时可以选择吃或者不吃,所以每个位置可能经过多次,不能简单的标记,这样考虑:
因为题目限制,那么必定吃的数字的顺序是1 2 3 ...依次递增,那么就把这个总的任务分解成从 0(开始)到1,从1到2...分别求最短路径的情况,单独处理每一段,最后累加所有的最短时间,肯定是最优解了。
4 5 2
.X..1
....X
.XX.S
.2.X.
3 3 1
S..
...
..1
10 10 9
.X...X.S.X
6..5X..X1X
...XXXX..X
X..9X...X.
8.X2X..X3X
...XX.X4..
XX....7X..
X..X..XX..
X...X.XX..
..X.......
Ac代码:
#include
#include
#include
using namespace std;
const int maxn=1005;
int n,m,k,dx[]={-1,1,0,0},dy[]={0,0,1,-1},vis[maxn][maxn];
char map[maxn][maxn];
struct maze
{
int x,y,time;
};
maze bfs(int bx,int by,char ch)
{
memset(vis,0,sizeof(vis));
queue q;
maze st={bx,by,0};
q.push(st);vis[bx][by]=1;
while(!q.empty())
{
st=q.front();q.pop();
if(map[st.x][st.y]==ch)
{
return st;
}
for(int i=0;i<4;++i)
{
int tx=st.x+dx[i],ty=st.y+dy[i];
if(tx<0||tx>=n||ty<0||ty>=m||map[tx][ty]=='X')//越界和墙
{
continue;
}
maze tp={tx,ty,st.time+1};
if(!vis[tx][ty])
{
vis[tx][ty]=1;
q.push(tp);
}
}
}
}
int main()
{
//freopen("shuju.txt","r",stdin);
while(~scanf("%d%d%d",&n,&m,&k))
{
int bx,by;
for(int i=0;i