【小测试,大题解】烈日中的BFS

        过了几天,夏天来了。朝阳似火,炙烤大地;老师严肃,严格无比……

        很快,一次“课堂测试”来了。(不过同学们都知道,这是一场考试)

        同学们刚落座,测试就开始了。小航马上打开文档,读起题来。

第一道题

【搜索与回溯算法】泡泡龙 (Standard IO)

时间限制: 1000 ms  空间限制: 262144 KB  具体限制  

题目描述:

这是一个简化版的网络游戏:在一个N×N方块构成的棋盘中,每个方块均涂上红、黄、蓝、绿(记为l、2、3、4)中的一种颜色,游戏者可以在最底行任意找一个方块,用鼠标双击这个方块,于是该方块及与之相邻(即在上、下、左、右四个方向上有公共边)的所有的同色方块均被消掉,而因下方失去支持的方块将会自由落下填补空位。样例中给出一个4×4的棋盘样例,当游戏者双击最底层左边第二个方块后,将会形成输出结果的布局。
你的任务是编写一个泡泡龙模拟程序,对于给定的一个初始棋盘,计算游戏者双击最底层某个方块后棋盘的布局将会如何。

输入:

第1行有两个正整数N和M(I≤M≤N≤I00),其中N表示棋盘的规模,而M则表示游戏者将双击最底层从左边数起的第M个方块。接下来的N行每行有N个l~4的整数组成,表示一个初始的棋盘,同一行相邻两个数之间用一个空格隔开。

输出:

N行,每行用N个数给出游戏结束后棋盘的布局,没有方块的格子用0表示,同一行相邻两个数之间也用一个空格分开。每行末尾有空格

样例输入:

4 2
1 2 3 4
4 2 4 4
3 4 4 3
1 4 4 3

样例输出

1 0 0 0
4 0 0 0
3 2 0 3
1 2 3 3

小航想道(思路):

1.这是道题目主体游戏,所以主题思路应该在与模拟。

2.输入以后,首先应通过搜索(可以用递归的方法开展搜索)来去掉方块(只要符合条件,将他们设置为零即可)【条件:在地图的范围之内,方块颜色与玩家所点击的方块颜色相同】

3.之后,可以另设一个数组,进行“去零操作”(用for循环实现)。

小航写道(代码):

#include<iostream>
using namespace std;
int n,m,a[105][105],b[105][105],fx[5]={0,-1,0,0,1},fy[5]={0,0,-1,1,0},visit[105][105];
void dg(int x,int y,int num)
{
	for(int i=1;i<=4;i++)
	{
		int nx=x+fx[i],ny=y+fy[i];
		if(a[nx][ny]==num&&visit[nx][ny]==0)
		{
			visit[nx][ny]=1;
			a[nx][ny]=0;
			dg(nx,ny,num);
			visit[nx][ny]=0;
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
		}
	}
	int nu=a[n][m];
	a[n][m]=0;
	dg(n,m,nu);
	int t;
	for(int i=1;i<=n;i++)
	{
		t=n;
		for(int j=n;j>=1;j--)
		{
			if(a[j][i]!=0)
			{
				b[t][i]=a[j][i];
				t--;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<b[i][j]<<" ";
		}
		cout<<endl;
	}
}


第二道题

跳马问题

     在n×m棋盘上有一中国象棋中的马,规定:

  1. 马走日字;
  2. 马只能往右走。
    要求马可以从棋盘的左下角(1,1)走到右上角(n,m)。请你编写程序,输出一条可行的路径。
    输入
    输入两个正整数n和m,表示棋盘的大小为n*m。
    输出
    输出一条可行的路径,用行列下标表示,并用“->”连接。
    样例输入
    9 5
    样例输出
    (1,1)->(3,2)->(5,1)->(6,3)->(7,1)->(8,3)->(9,5)

小航想道(思路):

1.马会有四种方向行走(本来有八种方向,但是题目要求只能往右走,因此就只剩下四种方向了),可以用以为或二维数组储存。

2.可以用深度优先搜索的方式实现,在过程中用二维数组储存路线,记得要回溯!

3.结束搜索(到达重点【右上角】)时,可以直接输出。输出后,题目的任务就完成了,可以用“exit(0)”来强制结束程序。

小航写道(程序)

注:本次的程序有详细注释,欢迎提建议

#include<iostream>
using namespace std;
int n,m,a[105][3],visit[70][70],step=1;
int fx[5]={0,-1,-2,2,1},fy[5]={0,-2,-1,1,2};
void dfs(int x,int y)
{
	if(x==m&&y==n)
	{
		for(int i=1;i<=step-2;i++)
		{
			cout<<"("<<a[i][1]<<","<<a[i][2]<<")->";//按照输出格式 
		}
		cout<<"("<<x<<","<<y<<")";
		exit(0);//强制结束程序 
	}
	for (int i=1;i<=4;i++)
	{
		int	nx=x+fx[i],ny=y+fy[i];//下一步可能在此点 
		if(nx>=1&&nx<=m&&ny>=1&&ny<=n&&visit[nx][ny]==0)//判断是否可以继续走 
		{
			a[step][1]=nx;
			a[step][2]=ny;//记录步骤 
			step++;
			visit[nx][ny]=1;//标记,防止重复 
			dfs(nx,ny);//dg(递归) 
			visit[nx][ny]=0; 
			step--;//回溯
		}
 
	}
	
}
int main()
{
	cin>>m>>n;
	a[step][1]=1;
	a[step][2]=1;//初始位置也要记录 
	step++;
	visit[1][1]=1;//标记 
	dfs(1,1);
}

        很快,”课堂小测“结束,小航赶紧提交了程序,刷新了界面,两个绿油油、让人看上去无比惬意的AC显现出来……

        “同学们,你们掌握得还不错”,接着,下课铃响了。

        “现在,你们要学的越来越多,学习任务更紧更多了,学习更加辛苦了,就如同夏天烈日。但是,坚持一下,烈日将变为暖阳,照亮你们的程序人生”看着快速收拾书包的同学们,TL老师意味深长地说道。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lyh不会打代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值