* 观察输入的格式,首先读入两个格子坐标以及之间边的类型,读入x1,y1,x2,y2,Gi后,两个格子的坐标可以压缩为z1,z2两个编号,直接g[z1][z2]=g[z2][z1]=Gi即可,因为是双向边,所以要存两次。接着读入哪些坐标放了钥匙,如果一个格子只放一把钥匙,直接key[z] = k即可,但是条件是可以放多把钥匙,就直接用key数组记录下该坐标下存放的所有钥匙的状态吧,读入时key[z] |= k就行了。BFS的过程不再赘述,放进队列里的应该是由格子编号z和持有钥匙状态st构成的二元组,初始状态是{1,key[1]},然后在队列非空时不断出队,取队头元素,尝试向四个方向转移,注意这里我是将格子编号从1开始,因此将其转化为坐标时需要先减一再加一。从0开始编号的话,x = z / m,y = z % m,m是列数;从1开始编号的话x = (z - 1) / m + 1,y = (z - 1) % m + 1,这里从1开始编号的转换特别容易出错。如果转移到棋盘外,或者遇见墙了就不向这个方向转移;如果从当前状态到下一个格子间有门,看下当前状态是否有该类门的钥匙,有就转移,不然不转移。转移到新格子后,新格子上有钥匙就尝试更新下状态,如果新格子的状态之前没有到达过就加入到队列里,到达终点就返回结果。