Problem Description
Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:
. 代表路
- 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
Output
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。
Sample Input
4 5 17
@A.B.
a*..
…^
c…b
4 5 16
@A.B.
a*..
…^
c…b
Sample Output
16
-1
这才理解位运算
/*
题目一共有10把钥匙,用二进制的1<<10代表每把钥匙的状态,比如:
1000000000 这个二进制的数字表示只拿到了第一把钥匙
每碰到一扇门,就用当前手中钥匙的状态按位与一下这个门的位置,
按位与出的结果是0,就代表有这把钥匙,否则没有
比如:现在手里的10把钥匙的状态是1000000000代表我只拿到了最高位的钥匙
也就是钥匙J
现在的门也是J 那么门的二进制表示就是 1000000000 他们按位与以后得到的
结果是1表示可以开门
每次碰到门就按位与判断,每次碰到钥匙就按位或更新当前手中钥匙的状态
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,t;
char mapp[25][25];
int sx,sy,ex,ey;
int dir[4][2]={-1,0,1,0,0,-1,0,1};
struct node{
int x,y;
int step;
int key;
};
int vis[25][25][(1<<10)+10];
bool check(int x,int y)
{
if(x<1||x>n||y<1||y>m||mapp[x][y]=='*'){
return false;
}
return true;
}
int bfs()
{
queue<node> q;
memset(vis,0,sizeof vis);
node first;
first.x=sx;
first.y=sy;
first.step=0;
first.key=0;
q.push(first);
node next;
while(q.size()){
node fr=q.front();
//cout<<fr.x<<endl;
q.pop();
if(fr.x==ex&&fr.y==ey){
return fr.step;
}
for(int i=0;i<4;i++){
next.x=fr.x+dir[i][0];
next.y=fr.y+dir[i][1];
next.key=fr.key;
next.step=fr.step;
if(!check(next.x,next.y)||vis[next.x][next.y][next.key]){
continue;
}
next.step++;
if(next.step>=t){
continue;
}
if(mapp[next.x][next.y]>='A'&&mapp[next.x][next.y]<='J'){
int tmp=mapp[next.x][next.y]-'A';
int flag=(next.key&(1<<tmp));
if(flag){
vis[next.x][next.y][next.key]=1;
q.push(next);
}
}
else if(mapp[next.x][next.y]>='a'&&mapp[next.x][next.y]<='j'){
int tmp=mapp[next.x][next.y]-'a';
next.key=(fr.key|(1<<tmp));
vis[next.x][next.y][next.key]=1;
q.push(next);
}
else{
//if(!vis[next.x][next.y][next.key]){
vis[next.x][next.y][next.key]=1;
q.push(next);
//}
}
}
}
return -1;
}
int main()
{
while(cin>>n>>m>>t){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>mapp[i][j];
if(mapp[i][j]=='@'){
sx=i;
sy=j;
}
else if(mapp[i][j]=='^'){
ex=i;
ey=j;
}
}
}
cout<<bfs()<<endl;
}
return 0;
}
下面是java代码 。。刚开始用java写题解
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import static java.lang.Integer.min;
import static java.lang.Math.*;
public class Main {
private static int n,m,t,sx,sy,ex,ey;
private static char[][] map=new char[25][25];
private static int[] dirx={-1,0,0,1};
private static int[] diry={0,1,-1,0};
public static void main(String[] args) throws Exception {
Scanner scanner=new Scanner(System.in);
while (scanner.hasNext()){
n=scanner.nextInt();
m=scanner.nextInt();
t=scanner.nextInt();
String str=null;
for (int i = 1; i <= n; i++) {
str=scanner.next();
//System.out.println(str.length());
for (int j = 0; j < str.length(); j++) {
map[i][j+1]=str.charAt(j);
if(str.charAt(j)=='@'){
sx=i;
sy=j+1;
}else if (str.charAt(j)=='^'){
ex=i;
ey=j+1;
}
}
}
System.out.println(bfs());
}
scanner.close();
}
public static int bfs(){
int[][][] vis=new int[25][25][1<<10+2];
class node{
private int x;
private int y;
private int step;
private int key;
public node(int x, int y, int step, int key) {
this.x = x;
this.y = y;
this.step = step;
this.key = key;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
}
Queue<node> q=new LinkedList<>();
q.offer(new node(sx,sy,0,0));
//
while(q.size()!=0){
node fr = new node(q.element().getX(),q.element().getY(),q.element().getStep(),q.element().getKey());
//System.out.println(q.element().getX()+" "+q.element().getY());
q.poll();
if (fr.getX()==ex&&fr.getY()==ey){
return fr.getStep();
}
for (int i = 0; i < 4; i++) {
node next = new node(fr.getX()+dirx[i],fr.getY()+diry[i],fr.getStep()+1,fr.getKey());
if (next.getX()<1||next.getX()>n||next.getY()<1||next.getY()>m||map[next.getX()][next.getY()]=='*'||vis[next.getX()][next.getY()][next.getKey()]==1){
continue;
}
if (next.getStep()>=t){
continue;
}
if(map[next.getX()][next.getY()]>='A'&&map[next.getX()][next.getY()]<='J'){
int tmp=map[next.getX()][next.getY()]-'A';
int flag = (next.getKey()&(1<<tmp));
if (flag!=0){
//next.setStep(fr.getStep()+1);
vis[next.getX()][next.getY()][next.getKey()]=1;
//System.out.println(next.getX()+"-->"+next.getY()+" AJ");
q.offer(new node(next.getX(),next.getY(),next.getStep(),next.getKey()));
}
}
else if(map[next.getX()][next.getY()]>='a'&&map[next.getX()][next.getY()]<='j'){
int tmp=map[next.getX()][next.getY()]-'a';
//int ans=(fr.getKey()|(1<<tmp));
next.setKey(fr.getKey()|(1<<tmp));
vis[next.getX()][next.getY()][next.getKey()]=1;
//next.setStep(fr.getStep()+1);
//System.out.println(next.getX()+"-->"+next.getY()+" aj");
q.offer(new node(next.getX(),next.getY(),next.getStep(),next.getKey()));
}
else{
vis[next.getX()][next.getY()][next.getKey()]=1;
//System.out.println(next.getX()+"-->"+next.getY()+" space");
q.offer(new node(next.getX(),next.getY(),next.getStep(),next.getKey()));
}
}
}
return -1;
}
}