题意:。。。
思路:
一开始, 我用 f[i][j][k] 表示在位置(i, j)有k个炸弹是否访问过。。
但是wa掉之后发现, 这个表示太大了,不能很好地刻画状态。。又想到加上 上一步的方向, 但是还是会把正确的状态给剪掉。。
既然, 数据是8x8, 为甚么不把整个map的访问状态保存下来呢?。。
参考了cxlove的blog
http://blog.youkuaiyun.com/acm_cxlove/article/details/7635497
______________________________________________________________________
再次思考BFS在隐式图上移动的情形。。。
在使用BFS时, 状态的表示决定了可以采取怎样的算法,剪枝等等。。。
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cassert>
#include <algorithm>
#include <cmath>
#include <climits>
#include <set>
#include <map>
using namespace std;
#define SPEED_UP iostream::sync_with_stdio(false);
#define FIXED_FLOAT cout.setf(ios::fixed, ios::floatfield);
#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))
typedef long long LL;
const int Maxn = 10;
const int Maxe = 580;
const int inf = INT_MAX/2;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};
char mm[Maxn][Maxn];
LL id[Maxn][Maxn];
int tot, sx, sy, ex, ey, m, n;
struct st {
// x, y: position
// t: time
// s: state of map as bitset( 0 for not visited, 1 for visited)
// a: amount of explosives
int x, y, t;
LL s;
int a;
st(int x, int y, int t, LL s, int a):x(x), y(y), t(t), s(s), a(a){}
bool operator < (const st &rhs) const {
return t > rhs.t;
}
};
void init() {
tot = 0;
rep(i, 0, n-1) {
cin >> mm[i];
rep(j, 0, m-1) {
char ch = mm[i][j];
if (ch == 'S') {
sx = i;sy = j;
}
else if (ch == 'D') {
ex = i;ey = j;
}
id[i][j] = i*m+j;
}
}
}
void print(const st &i) {
cout << "pos:" << i.x << ", " << i.y << " t: " << i.t << " a: " << i.a << " { ";
rep(j, 0, 31)
if ( (1<<j)&i.s ) cout << j << ' ';
cout << "}\n";
}
#define BIT_ADD(s, i) ((s)|(1ll<<(i)))
#define BIT_HAS(s, i) ((s)&(1ll<<(i)))
int solve() {
priority_queue<st> q;
// t[x][y][k] 在 (x, y)有k个炸弹
// 保存地图的状态
set<LL> t[Maxn][Maxn][Maxe];
q.push(st(sx, sy, 0, BIT_ADD(0ll, id[sx][sy]), 0));
while (!q.empty()) {
st fr = q.top();q.pop();
if (t[fr.x][fr.y][fr.a].count(fr.s)) continue;
t[fr.x][fr.y][fr.a].insert(fr.s);
//print(fr);
if (fr.x == ex && fr.y == ey) {
return fr.t;
}
int nx, ny;
char ch;
rep(i, 0, 3) {
nx = fr.x + dx[i];
ny = fr.y + dy[i];
if (0 <= nx && nx < n && 0 <= ny && ny < m) {
ch = mm[nx][ny];
if (ch == 'X') {
if ( BIT_HAS(fr.s, id[nx][ny]) )
q.push( st(nx, ny, fr.t+1, fr.s, fr.a) );
else if (fr.a) q.push( st(nx, ny, fr.t+2, BIT_ADD(fr.s, id[nx][ny]), fr.a-1) );
}
else if (isdigit(ch)) {
if ( BIT_HAS(fr.s, id[nx][ny]) )
q.push( st(nx, ny, fr.t+1, fr.s, fr.a) );
else
q.push( st(nx, ny, fr.t+1, BIT_ADD(fr.s, id[nx][ny]), fr.a+ch-'0') );
}
else {
q.push( st(nx, ny, fr.t+1, /*BIT_ADD(fr.s, id[nx][ny])*/fr.s, fr.a) );
}
}
}
}
return -1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
while (cin >> n >>m && (n && m)) {
init();
cout << solve() << endl;
}
return 0;
}