题目描述
Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
输入
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:
. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
输出
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。
样例
Sample Input
4 5 17
@A.B.
a*.*.
*..*^
c..b*
4 5 16
@A.B.
a*.*.
*..*^
c..b*
Sample Output
16
-1
题意
这个题就是要对钥匙的个数进行二进制的^与 &,然后直接BFS就行,写的时候思路很正确,代码写傻逼了 ,一直wa mdezz
AC代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
#define ls st<<1
#define rs st<<1|1
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define LL long long
#define PII pair<int,int>
#define VI vector<int>
#define CLR(a,b) memset(a, (b), sizeof(a))
#define ALL(x) x.begin(),x.end()
#define rep(i,s,e) for(int i=(s); i<=(e); i++)
#define tep(i,s,e) for(int i=(s); i>=(e); i--)
const int INF = 0x3f3f3f3f;
const int MAXN = 50+10;
const int mod = 1e9+7;
const double eps = 1e-8;
void fe() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt","w",stdout);
#endif
}
LL read()
{
LL x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
int n, m, t, sx, sy;
bool flag;
bool vis[MAXN][MAXN][1<<10];
char mps[MAXN][MAXN];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
struct node {
int x, y, st, v;
node(int _x=0, int _y=0, int _st=0, int _v=0):x(_x),y(_y),st(_st),v(_v){}
};
bool check(int x, int y) {
return x>=0&&x<n&&y>=0&&y<m&&mps[x][y]!='*';
}
void bfs() {
queue<node> que;
que.push(node(sx,sy,0,0));
vis[sx][sy][0] = true;
while(!que.empty()) {
node tmp = que.front();
que.pop();
if(mps[tmp.x][tmp.y] == '^') {
if(tmp.st < t) {
cout << tmp.st << endl;
}
else
flag = false;
return ;
}
if(tmp.st >= t) {
flag = false;
return;
}
for(int i = 0; i < 4; i++) {
int x = tmp.x+dx[i];
int y = tmp.y+dy[i];
if(check(x,y)) {
if(mps[x][y]>='a' && mps[x][y]<='z') {
int v = tmp.v|(1<<(mps[x][y]-'a'));
if(!vis[x][y][v]) {
vis[x][y][v] = true;
que.push(node(x,y,tmp.st+1,v));
}
}
else if(mps[x][y]>='A' && mps[x][y]<='Z') {
int v = tmp.v&(1<<(mps[x][y]-'A'));
if(!vis[x][y][tmp.v] && v) {
vis[x][y][tmp.v] = true;
que.push(node(x,y,tmp.st+1,tmp.v));
}
}
else {
if(!vis[x][y][tmp.v]) {
vis[x][y][tmp.v] = true;
que.push(node(x,y,tmp.st+1,tmp.v));
}
}
}
}
}
flag = false;
return ;
}
int main(int argc, char const *argv[]) {
while(cin >> n >> m >> t) {
flag = true;
CLR(vis,false);
CLR(mps,0);
for(int i = 0; i < n; i++)
cin >> mps[i];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(mps[i][j] == '@') {
sx = i, sy = j;
}
}
}
bfs();
if(!flag)
cout << -1 << endl;
}
return 0;
}