c++ 孤岛营救问题
作者:互联网
孤岛营救问题
题目描述
1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩。瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图。迷宫的外形是一个长方形,其南北方向被划分为N 行,东西方向被划分为M列,于是整个迷宫被划分为 N×M 个单元。每一个单元的位置可用一个有序数对(单元的行号,单元的列号)来表示。南北或东西方向相邻的 2 个单元之间可能互通,也可能有一扇锁着的门,或者是一堵不可逾越的墙。迷宫中有一些单元存放着钥匙,并且所有的门被分成 P类,打开同一类的门的钥匙相同,不同类门的钥匙不同。
大兵瑞恩被关押在迷宫的东南角,即(N,M)单元里,并已经昏迷。迷宫只有一个入口,在西北角。也就是说,麦克可以直接进入(1,1)单元。另外,麦克从一个单元移动到另一个相邻单元的时间为1,拿取所在单元的钥匙的时间以及用钥匙开门的时间可忽略不计。
试设计一个算法,帮助麦克以最快的方式到达瑞恩所在单元,营救大兵瑞恩。
输入
第 1行有 3个整数,分别表示N,M,P的值。[均小于等于10]
第 2 行是1个整数 K[小于等于150],表示迷宫中门和墙的总数。
第 I+2 行(1<=I<=K) ,有 5 个整数,依次为Xi1,Yi1,Xi2,Yi2,Gi: 当Gi>=1时,表示(Xi1,Yi1)单元与(Xi2,Yi2)单元之间有一扇第Gi类的门,当 Gi=0时,表示(Xi1,Yi1)单元与(Xi2,Yi2)单元之间有一堵不可逾越的墙(其中,|Xi1-Xi2|+|Yi1-Yi2|=1,0<=Gi<=P) 。
第K+3行是一个整数S,表示迷宫中存放的钥匙总数。
第K+3+J 行(1<=J<=S),有3个整数, 依次为Xi1,Yi1,Qi: 表示第J 把钥匙存放在(Xi1,Yi1)单元里,并且第J 把钥匙是用来开启第Qi类门的。 (其中 1<=Qi<=P) 。
输入数据中同一行各相邻整数之间用一个空格分隔。
输出
程序运行结束时,将麦克营救到大兵瑞恩的最短时间的值输出。如果问题无解,则输出-1。
样例输入
4 4 9
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1
样例输出
14
提示
存在一个格子有多把钥匙的情况
AC代码
#include <stdio.h>
#include <string.h>
int n,m,p,k;
int d[11][11][11][11];
int kn,g[11][11][100],gn[11][11];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct point
{
char x,y;
int step;
bool key[11];
};
int fun(point u)
{
int ans = 0,p = 1;
for (int i = 1;i <= 10;i ++)
{
ans += p * u.key[i];
p = p * 2;
}
return ans;
}
point q[650000],s;
bool used[11][11][1024];
int f,e;
int main()
{
scanf("%d%d%d",&n,&m,&p);
scanf("%d",&k);
memset(used,0,sizeof(used));
memset(g,0,sizeof(g));
for(int i=1;i<=k;i++)
{
int a1,b1,a2,b2;
scanf("%d%d%d%d",&a1,&b1,&a2,&b2);
scanf("%d",&d[a1][b1][a2][b2]);
if(d[a1][b1][a2][b2]==0)
d[a1][b1][a2][b2]=-1;
d[a2][b2][a1][b1]=d[a1][b1][a2][b2];
}
scanf("%d",&kn);
memset(gn,0,sizeof(gn));
for(int i=1;i<=kn;i++)
{
int a1,b1;
scanf("%d%d",&a1,&b1);
gn[a1][b1]++;
scanf("%d",&g[a1][b1][gn[a1][b1]]);
}
s.x=1,s.y=1,s.step=0;
memset(s.key,0,sizeof(s.key));
q[1]=s;
int f=1,e=1;
while(f<=e)
{
point u=q[f++];
for(int i=0;i<4;i++)
{
point v=u;
v.x=u.x+dx[i];
v.y=u.y+dy[i];
v.step=u.step+1;
memcpy(v.key,u.key,sizeof(u.key));
if(v.x<1||v.x>n||v.y<1||v.y>m)continue;
if(d[u.x][u.y][v.x][v.y]==-1)continue;
if (used[v.x][v.y][fun(v)] == 1) continue;
if(d[u.x][u.y][v.x][v.y]>0)
{
if(u.key[d[u.x][u.y][v.x][v.y]]==0)continue;
}
if(gn[v.x][v.y]>0)
{
for(int j=1;j<=gn[v.x][v.y];j++)
v.key[g[v.x][v.y][j]]=1;
}
if(v.x==n&&v.y==m)
{
printf("%d\n",v.step);
return 0;
}
e++;
q[e]=v;
used[v.x][v.y][fun(v)] = 1;
}
}
printf("-1\n");
return 0;
}
(未完待续)
标签:11,int,迷宫,c++,瑞恩,孤岛,麦克,营救,单元 来源: https://www.cnblogs.com/LJA001162/p/11299904.html