0
点赞
收藏
分享

微信扫一扫

2022.1.13 学习总结

alanwhy 2022-01-13 阅读 81

题目给出的地图中共有四类东西:玉米地、草地、传送门、牛。

其中,玉米地不能走,其余的位置都能走,每走一步花费一个单位的时间,到达传送门时会被传送至另一扇相同类型传送门初,且不会花费时间。

我的思路是设一个标记数组来记录走过地方,由于传送门可以使用两次,刚好一去一回,两个传送门的坐标都只被标记了一次,所以设数组来记录路径在这里应该是没有问题的。

很明显,这道题需要使用BFS。

把“找出起点和终点”的工作放在输入中会减少不少的程序累赘工作,找到起点和终点并将它们标记后将起点压入队列并做好标记,而后就可以开始进行你的bfs了

选取好一个点后对其向四个方向进行扩展,记得做好剪枝处理。

只是最后还是存在问题,我暂时还没发现,还需要后续进行修改。。。

(这里放上代码只是做个思路参考,直接交是错的)

#include<stdio.h>
char map[1000][1000];//存储地图 
int book[1000][1000];//定义标记数组
int n,m,head=0,tail=0,x1,y2;
int shi[2]={-1,-1},mo[2]={-1,-1};
//定义方向数组
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//右、左、上、下 
struct abc 
{
	int x,y,step;
}que[500000];
void deliver(int x,int y,char k)//传送门转点 
{
	int k1,k2;
	for(k1=0;k1<n;k1++)
	{
		for(k2=0;k2<m;k2++)
		{
			if( k1 != x && k2 != y && map[k1][k2] == k)
			{
				x1=k1;
				y2=k2;
				return ;
			}
		}
	}
}
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
	scanf("%s",map[i]);
	for(i=0;i<n;i++)//找出起点和终点 
	{
		for(j=0;j<m;j++)
		{
			if(map[i][j] == '@')
			{
				shi[0]=i;
				shi[1]=j;
			}
			if(map[i][j] == '=')
			{
				mo[0]=i;
				mo[1]=j;
			}
			if(shi[0] !=-1 && mo[0] != -1)
			break;
		}
	}
//  printf("shi[0]=%d shi[1]=%d\nmo[0]=%d mo[1]=%d\n",shi[0],shi[1],mo[0],mo[1]);
	book[shi[0]][shi[1]]=1;//对起点标记 
	que[tail].x=shi[0];//将起点压入队列 
	que[tail].y=shi[1];
	que[tail++].step=0;//初始步数为0 
	while( head < tail)
	{
		for(i=0;i<4;i++)//分别向四个方向遍历 
		{
			int tx,ty;
			tx=que[head].x+next[i][0];
			ty=que[head].y+next[i][1];
			//剪枝 
			if(tx < 0 || tx >= n || ty < 0 || ty >= m|| book[tx][ty] != 0 || map[tx][ty] == '#')
			continue;
			que[tail].x=tx;//将可取点压入队列 
			que[tail].y=ty;
			que[tail].step=que[head].step+1;
			if(map[tx][ty] >='A' && map[tx][ty] <='Z')//判断是否在传送门上 
			{
				deliver(tx,ty,map[tx][ty]);
				que[tail].x=x1;
				que[tail].y=y2;
			}
			if(tx == mo[0] && ty == mo[1])//判断是否到终点 
			{
				printf("%d\n",que[tail].step);
				return 0;
			}
			tail++;//尾指针后移 
		}
		head++;//头指针后移 
	}	
	return 0;
}

昨天说这道题的代码还有点瑕疵。

找出原因后明白是因为我的代码是直接修改原地图,这样就造成了邻近的单词或交错的单词会有误判的情况。

要修改也很简单,加上一个标记数组就好了。

#include<stdio.h>
int n;
char a[1000][1000],k1[2000],k2[2000];
//定义方向常量数组
int book[1000][1000];//用于标记数组 
int next[8][2]={{0,1},{0,-1},{1,0},{-1,0},{-1,1},{-1,-1},{1,1},{1,-1}};
//右、左、上、下、下右、下左、上右、上左 
void dfs(int x,int y,int k,int flag)
{
	if(x < 0 ||x >=n || y < 0 || y >=n)
	return;
	int i,j;
	if(k == -100)
   {
	for(i=0;i<8;i++)
	{
		int tx,ty;
		tx=x+next[i][0];
		ty=y+next[i][1];
		if(tx < 0 || tx >= n || ty < 0 || ty >= n)
		continue;
		if(a[tx][ty] == 'i')
			dfs(tx,ty,i,1);
		k=-100;
	}
   }
   if(k != -100)
   {
   	int tx,ty,i1;
   tx=x+next[k][0];
   ty=y+next[k][1];
   if(tx < 0 || tx >= n || ty < 0 || ty >= n)
   return;
    if(a[tx][ty] == 'z' && flag== 1)
    	dfs(tx,ty,k,2);
	if(a[tx][ty] == 'h' && flag == 2)
    	dfs(tx,ty,k,3);
	if(a[tx][ty] == 'o' && flag == 3)
    	dfs(tx,ty,k,4);
	if(a[tx][ty] == 'n' && flag == 4)
    	dfs(tx,ty,k,5);
	if(a[tx][ty] == 'g' && flag == 5)
    {
    	book[tx][ty]='7';
    	book[tx-next[k][0]][ty-next[k][1]]='6';
    	book[tx-2*next[k][0]][ty-2*next[k][1]]='5';
    	book[tx-3*next[k][0]][ty-3*next[k][1]]='4';
    	book[tx-4*next[k][0]][ty-4*next[k][1]]='3';
    	book[tx-5*next[k][0]][ty-5*next[k][1]]='2';
    	book[tx-6*next[k][0]][ty-6*next[k][1]]='1';
    	return ;
	}
   }
   return ;
}

int main()
{
   scanf("%d",&n);
   int i,j,k=0;
   for(i=0;i<n;i++)
   scanf("%s",a[i]);
   for(i=0;i<n;i++)
   {
	for(j=0;j<n;j++)
	{
	if(a[i][j] == 'y')//记录所有'y'字母的坐标 
	 {
		k1[k]=i;
		k2[k]=j;
		k++;
	 }
    }
   }
   for(i=0;i<k;i++) 
   dfs(k1[i],k2[i],-100,0);
   for(i=0;i<n;i++)
{
   for(j=0;j<n;j++)
   {
   	if(book[i][j] == '1')
   	a[i][j]='y';
   	else
   	{if(book[i][j] == '2')
   	a[i][j]='i';
   	else
   	{if(book[i][j] == '3')
   	a[i][j]='z';
   	else
   	{if(book[i][j] == '4')
   	a[i][j]='h';
   	else
   	{if(book[i][j] == '5')
   	a[i][j]='o';
   	else
   	{if(book[i][j] == '6')
   	a[i][j]='n';
   	else
   	{if(book[i][j] == '7')
   	a[i][j]='g';
   	else
   	a[i][j]='*';
    }}}}}}
   }
}
   for(i=0;i<n;i++)
   {printf("%s",a[i]);
   if(i != n-1)
   printf("\n");}
	return 0;
}

( + 记单词  2.5 h )

举报

相关推荐

2022.1.13学习总结

2022.1.13

学习总结。。。。

学习总结!

FineBI学习总结

2022.1.20 学习总结

近日学习总结

0 条评论