zoukankan      html  css  js  c++  java
  • NOI2.5 4980:拯救行动

    描述

    公主被恶人抓走,被关押在牢房的某个地方。牢房用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

    这道题刚开始纯洁地想:广搜,遇小兵加2,遇地板加1,结果没错,0分…………(T—T)


    错误代码:


    <span style="background-color: rgb(255, 255, 153);"><span style="font-size:12px;">#include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char c[201];
    int z[4]={1,-1,0,0},u[4]={0,0,-1,1},m,n,xz,yz,num,nn,v[201][201];
    void find(int p,int q)
    {
    	int x=0,y=0,t=0,w=1,i;
    	int h[100001][3];
    	h[1][0]=p;
    	h[1][1]=q;
    	h[1][2]=0;
    	do
    	{
    		t++;
    		for(i=0;i<4;i++)
    		{
    			x=h[t][0]+z[i];
    			y=h[t][1]+u[i];
    			if(x>=0&&x<m&&y>=0&&y<n&&v[x][y])
    			{
    				w++;
    				h[w][0]=x;
    				h[w][1]=y;
    				h[w][2]=h[t][2]+v[x][y];
    				v[x][y]=0;
    				if(x==xz&&y==yz)
    				{
    					num=h[w][2];
    					return ;
    				}
    			}
    		}
    	}while(t<w);
    }
    int main()
    {
    	int i,j,x,y;
    	scanf("%d",&nn);
    	for(int f=0;f<nn;f++)
    	{
    		scanf("%d%d",&m,&n);
    		num=0;
    		for(i=0;i<m;i++)
    		{
    			scanf("%s",c);
    			for(j=0;j<=n;j++)
    			{
    				if(c[j]=='#')
    					v[i][j]=0;
    				if(c[j]=='r')
    				{
    					x=i;
    					y=j;
    					v[i][j]=1;
    				}
    				if(c[j]=='a')
    				{
    					xz=i;
    					yz=j;
    					v[i][j]=1;
    				}
    				if(c[j]=='@')
    					v[i][j]=1;
    				if(c[j]=='x')
    					v[i][j]=2;
    			}
    		}
    		find(x,y);
    		if(num==0)
    			printf("Impossible
    ");
    		else
    			printf("%d
    ",num);
    	}
    }</span></span>

    看来这道题是一道   不 错(wei suo) 的题目,后来想想,假设地板有一滴血,小兵有两滴血,主角的攻击力为一,那么遇到地板,创造一个节点,记录,然后一脚踹死地板,遇到小兵,创造一个节点,记录,然后打一下,小兵还剩一滴血,在第二次找的时候,发现小兵没死,再一脚踹死,并再创造一个节点,记录

    结果……

    0分……


    错误代码:

    <span style="background-color: rgb(255, 255, 153);">#include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char c[201];
    int z[4]={1,-1,0,0},u[4]={0,0,-1,1},m,n,xz,yz,num,nn,v[201][201];
    void find(int p,int q)
    {
    	int x=0,y=0,t=0,w=1,i;
    	int h[100001][3];
    	h[1][0]=p;
    	h[1][1]=q;
    	h[1][2]=0;
    	do
    	{
    		t++;
    		if(!v[h[t][0]][h[t][1]])
    		{
    			for(i=0;i<4;i++)
    			{
    				x=h[t][0]+z[i];
    				y=h[t][1]+u[i];
    				if(!v[h[t][0]][h[t][1]])
    				{
    					if(x>=0&&x<m&&y>=0&&y<n&&v[x][y])
    					{
    						w++;
    						h[w][0]=x;
    						h[w][1]=y;
    						h[w][2]=h[t][2]+1;
    						v[x][y]--;
    						if(x==xz&&y==yz)
    						{
    							num=h[w][2];
    							return ;
    						}
    					}
    				}
    			}
    		}
    		else
    		{
    			w++;
    			h[w][0]=h[t][0];
    			h[w][1]=h[t][1];
    			h[w][2]=h[t][2]+1;
    			v[h[w][0]][h[w][1]]=0;
    			if(x==xz&&y==yz)
    			{
    				num=h[w][2];
    				return ;
    			}
    		}
    	}while(t<w);
    }
    int main()
    {
    	int i,j,x,y;
    	scanf("%d",&nn);
    	for(int f=0;f<nn;f++)
    	{
    		for(i=0;i<=200;i++)
    			memset(v[i],0,sizeof(v[i]));
    		scanf("%d%d",&m,&n);
    		num=0;
    		for(i=0;i<m;i++)
    		{
    			scanf("%s",c);
    			for(j=0;j<=n;j++)
    			{
    				if(c[j]=='#')
    					v[i][j]=0;
    				if(c[j]=='r')
    				{
    					x=i;
    					y=j;
    					v[i][j]=0;
    				}
    				if(c[j]=='a')
    				{
    					xz=i;
    					yz=j;
    					v[i][j]=1;
    				}
    				if(c[j]=='@')
    					v[i][j]=1;
    				if(c[j]=='x')
    					v[i][j]=2;
    			}
    		}
    		find(x,y);
    		if(num==0)
    			printf("Impossible
    ");
    		else
    			printf("%d
    ",num);
    	}
    }</span>

    干得漂亮(ma  de  zhi  zhang)!完美地Wa了

    后来发现在广搜的时候,如果遇到小兵,踹死了,第二条路走过来的时候,就直接从尸体上跨过去了,根本无视(he he),所以要用两个map来记录


    一交



    终于AC了……………………


    正确代码:


    <span style="background-color: rgb(255, 255, 153);">#include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char c[201];
    int z[4]={1,-1,0,0},u[4]={0,0,-1,1},m,n,xz,yz,num,nn,v[201][201][2];
    void find(int p,int q)
    {
    	int x=0,y=0,t=0,w=1,i;
    	int h[100001][4];
    	h[1][0]=p;
    	h[1][1]=q;
    	h[1][2]=0;
    	h[1][3]=1;
    	do
    	{
    		t++;
    		if(!v[h[t][0]][h[t][1]][0])
    		{
    			for(i=0;i<4;i++)
    			{
    				x=h[t][0]+z[i];
    				y=h[t][1]+u[i];
    				if(x>=0&&x<m&&y>=0&&y<n&&!v[x][y][1]&&v[x][y][0])
    				{
    					w++;
    					h[w][0]=x;
    					h[w][1]=y;
    					h[w][2]=h[t][2]+1;
    					h[w][3]=t;
    					v[x][y][0]--;
    					v[x][y][1]=1;
    					if(x==xz&&y==yz)
    					{
    						num=h[w][2];
    						return;
    					}
    				}
    			}
    		}
    		if(v[h[t][0]][h[t][1]][0])
    		{
    			w++;
    			h[w][0]=h[t][0];
    			h[w][1]=h[t][1];
    			h[w][2]=h[t][2]+1;
    			h[w][3]=t;
    			v[x][y][1]=1;
    			v[h[w][0]][h[w][1]][0]=0;
    		}
    	}while(t<w);
    }
    int main()
    {
    	int i,j,x,y;
    	scanf("%d",&nn);
    	for(int f=0;f<nn;f++)
    	{
    		for(i=0;i<=200;i++)
    			memset(v[i],0,sizeof(v[i]));
    		scanf("%d%d",&m,&n);
    		num=0;
    		for(i=0;i<m;i++)
    		{
    			scanf("%s",c);
    			for(j=0;j<=n;j++)
    			{
    				if(c[j]=='#')
    					v[i][j][0]=0;
    				if(c[j]=='r')
    				{
    					x=i;
    					y=j;
    					v[i][j][0]=0;
    				}
    				if(c[j]=='a')
    				{
    					xz=i;
    					yz=j;
    					v[i][j][0]=1;
    				}
    				if(c[j]=='@')
    					v[i][j][0]=1;
    				if(c[j]=='x')
    					v[i][j][0]=2;
    			}
    		}
    		find(x,y);
    		if(num==0)
    			printf("Impossible
    ");
    		else
    			printf("%d
    ",num);
    	}
    }</span>

    功夫不负有心人啊!!!!!!
  • 相关阅读:
    MFC tab页面中获到其它页面的数据
    sqlite数据库中"Select * From XXX能查到数据,但是Select DISTINCT group From xxx Order By group却查不出来
    关闭程序出现崩溃(exe 已触发了一个断点及未加载ucrtbased.pdb)
    springboot 通用Mapper使用
    springBoot 发布war包
    springCloud Zuul网关
    springboot hystrix turbine 聚合监控
    springBoot Feign Hystrix Dashboard
    springBoot Ribbon Hystrix Dashboard
    springBoot Feign Hystrix
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12002578.html
Copyright © 2011-2022 走看看