【搜索】 noi openjudge 2.5 拯救行动

    xiaoxiao2026-04-15  5

    题目:

    4980:拯救行动

    总时间限制:  10000ms  内存限制:  65536kB 描述

    公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。  英勇的骑士(r)决定孤身一人去拯救公主(a)。我们假设拯救成功的表示是“骑士到达了公主所在的位置”。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。  现假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要1个单位时间,杀死一个守卫需要花费额外的1个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。

    给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,请你计算拯救行动成功需要花费最短时间。

    输入 第一行为一个整数S,表示输入的数据的组数(多组输入) 随后有S组数据,每组数据按如下格式输入  1、两个整数代表N和M, (N, M <= 200).  2、随后N行,每行有M个字符。"@"代表道路,"a"代表公主,"r"代表骑士,"x"代表守卫, "#"代表墙壁。 输出 如果拯救行动成功,输出一个整数,表示行动的最短时间。 如果不可能成功,输出"Impossible" 样例输入 2 7 8 #@#####@ #@a#@@r@ #@@#x@@@ @@#@@#@# #@@@##@@ @#@@@@@@ @@@@@@@@ 13 40 @x@@##x@#x@x#xxxx##@#x@x@@#x#@#x#@@x@#@x xx###x@x#@@##xx@@@#@x@@#x@xxx@@#x@#x@@x@ #@x#@x#x#@@##@@x#@xx#xxx@@x##@@@#@x@@x@x @##x@@@x#xx#@@#xxxx#@@x@x@#@x@@@x@#@#x@# @#xxxxx##@@x##x@xxx@@#x@x####@@@x#x##@#@ #xxx#@#x##xxxx@@#xx@@@x@xxx#@#xxx@x##### #x@xxxx#@x@@@@##@x#xx#xxx@#xx#@#####x#@x xx##@#@x##x##x#@x#@a#xx@##@#@##xx@#@@x@x x#x#@x@#x#@##@xrx@x#xxxx@##x##xx#@#x@xx@ #x@@#@###x##x@x#@@#@@x@x@@xx@@@@##@@x@@x x#xx@x###@xxx#@#x#@@###@#@##@x#@x@#@@#@@ #@#x@x#x#x###@x@@xxx####x@x##@x####xx#@x #x#@x#x######@@#x@#xxxx#xx@@@#xx#x#####@ 样例输出 13 7 分析: 一道经典的广搜题目,不过多加了一个‘守卫’,至于广搜是什么,不造的同学还是去看书吧,我这里就说一下如何处理‘守卫’ 用一个bool f[][]来标明此处是否有守卫 若f[][]=1,那么拓展出的节点就是本身,再把f[][]置为0 代码如下: #include<cstdio> #include<cstring> int n,m,dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}},sum,pre[40010],x,y; char s[210][210]; void leiji(int d) { if(pre[d]==0) return; sum++; leiji(pre[d]); } int main() { int a[40010],b[40010],head=0,tail=1,t; bool f[210][210]; scanf("%d",&t); for(int p=1;p<=t;p++) { memset(f,0,sizeof(f)); scanf("%d%d\n",&n,&m); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%c",&s[i][j]); if(s[i][j]=='r') x=i,y=j; if(s[i][j]=='x') f[i][j]=1; } scanf("\n"); } head=0,tail=1; s[x][y]='#'; a[1]=x,b[1]=y; while(head<tail) { head++; for(int i=0;i<=3;i++) { if(f[a[head]][b[head]]) { x=a[head],y=b[head]; f[x][y]=0; tail++; a[tail]=x; b[tail]=y; pre[tail]=head; break; } x=a[head]+dir[i][0],y=b[head]+dir[i][1]; if(x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='#') { tail++; a[tail]=x; b[tail]=y; pre[tail]=head; if(s[x][y]=='a') {leiji(tail);break;} s[x][y]='#'; } } if(sum) {printf("%d\n",sum);break;} } if(!sum) printf("Impossible\n"); sum=0; } }

    转载请注明原文地址: https://ju.6miu.com/read-1308854.html
    最新回复(0)