http://hihocoder.com/contest/hiho166/problem/1
用x, y, key描述状态,key二进制表示的第i为为1时表示已经拥有了第i把钥匙。
不知道为啥只过了70/100,TLE了
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <stdio.h>
using namespace std;
char board[105][105];
int n, m, k;
int sRow, sCol, eRow, eCol;
//int keyRow[6], keyCol[6];
int dr[4] = { 0, 0, 1, -1 };
int dc[4] = { -1, 1, 0, 0 };
bool visited[105][105][32];
unordered_map<uint64_t, int> keyPos;
struct point {
int r, c, key, step;
point() {}
point(int _r, int _c, int _k, int _s) : r(_r), c(_c), key(_k), step(_s) {}
};
void addKey(int & key, int i) {
key |= 1 << i;
}
bool valid(int r, int c, int key) {
if (visited[r][c][key]) {
return false;
}
if (r < 0 || r >= n || c < 0 || c >= m || board[r][c] == '#') {
return false;
}
if (board[r][c] == '.') {
return true;
}
int i = board[r][c] - 'A';
return key & (1 << i);
}
int bfs(int _sRow, int _sCol, int _eRow, int _eCol) {
queue<point> Q;
int init_key = 0;
/*
for (int i = 0; i < k; ++i) {
if (sRow == keyRow[i] && sCol == keyCol[i]) {
addKey(init_key, i);
}
}*/
uint64_t tmpK = static_cast<uint64_t>(_sRow) << 32 | static_cast<uint64_t>(_sCol);
if (keyPos.find(tmpK) != keyPos.end()) {
addKey(init_key, keyPos[tmpK]);
}
point begin(_sRow, _sCol, init_key, 0);
visited[_sRow][_sCol][init_key] = true;
Q.push(begin);
int ans = -1;
while (!Q.empty()) {
point cur = Q.front();
Q.pop();
//cout << "pos : r : " << cur.r << " c : " << cur.c << " key " << cur.key << endl;
if (cur.r == _eRow && cur.c == _eCol) {
ans = cur.step;
return ans;
}
visited[cur.r][cur.c][cur.key] = true;
for (int i = 0; i < 4; ++i) {
int r = cur.r + dr[i], c = cur.c + dc[i];
if (valid(r, c, cur.key)) {
int tmpKey = cur.key;
/*
for (int j = 0; j < k; ++j) {
if (r == keyRow[j] && c == keyCol[j]) {
addKey(tmpKey, j);
}
}*/
uint64_t tmpK = static_cast<uint64_t>(r) << 32 | static_cast<uint64_t>(c);
if (keyPos.find(tmpK) != keyPos.end()) {
addKey(tmpKey, keyPos[tmpK]);
}
point tmp(r, c, tmpKey, cur.step + 1);
Q.push(tmp);
}
}
}
return ans;
}
int main() {
//while (scanf("%d %d %d %d %d %d %d", &n, &m, &k, &sRow, &sCol, &eRow, &eCol) != EOF) {
//cin >> n >> m >> k >> sRow >> sCol >> eRow >> eCol;
while(cin >> n >> m >> k >> sRow >> sCol >> eRow >> eCol){
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> board[i][j];
}
}
for (int i = 0; i < k; ++i) {
//cin >> keyRow[i] >> keyCol[i];
int r, c;
//cin >> r >> c;
scanf("%d %d", &r, &c);
uint64_t tmpK = static_cast<uint64_t>(r) << 32 | static_cast<uint64_t>(c);
keyPos[tmpK] = i;
}
memset(visited, false, sizeof(visited));
int ans = bfs(sRow, sCol, eRow, eCol);
//cout << ans << endl;
printf("%d\n", ans);
//cin >> n;
}
return 0;
}