算法:求最大公倍数和走迷宫

1,最大公倍数

题目:多case练习

大数据用:longlong
如果输入0,0标志结束输入:while (scanf("%lld%lld", &n, &m), n&&m)
求最大公倍数:

long long fun(long long n, long long m)
{
	long long result;
	long long r;
	long long x = n*m;
	while ((r=n%m)!=0)
	{
		n = m;
		m = r;
	}
	result = x / m;
	return result;
}

2,走迷宫

Description
有一个N*M的格子迷宫,1代表该格子为墙,不能通过,0代表可以通过,另外,在迷宫中
有一些传送门,走到传送门的入口即会自动被传送到传送门的出口(一次传送算1步)。人在迷宫中可以尝试
上下左右四个方向移动。现在给定一个迷宫和所有传送门的出入口,以及起点和终点,
问最少多少步可以走出迷宫。如果不能走出迷宫输出“die”。

输入格式
该程序为多CASE,第1行为CASE的数量
每一个CASE,第1行为两个数N(行)和M(列)
然后N行每行M个数
之后是一个数W,为传送门的数量
之后每行一个传送门的入口坐标c1(行),r1(列)和出口坐标c2,r2
之后是起点坐标和终点坐标sc(行) sr(列) ec(行) er(列)

注:传送门出入口和起点坐标和终点坐标不会出现在墙的位置
所有数字不超过100

2 case数
4 3 N*M
011
011
110
110

1 传送门数

1 0 2 2 传送门的入口坐标traR(行),traC(列)和出口坐标arriveR,arriveC
0 0 3 2 起点坐标和终点坐标starR(行), starC(列)和 endR(行) endC(列)
2 2

01
10
0
0 0 1 1

心得:

BFS的关键是queue的应用,在此处的step代替了visited的作用,原因是只能上下左右移动一步,相当于图中的定点与周围距离为1的顶点可以联通
输入地图时没有空格,所以map的数据类型应该是char
注意使用ROW和COL而非使用x和y
用数组模拟上下左右的坐标变化,并用变量i来控制
注意是否到终点的判断语句在循环中的位置

#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<utility>
#include<cstdio>
using namespace std;
const int MAX_R = 100;
const int MAX_C = 100;
typedef pair<int, int> P;
void bfs()
{
	//步数兼职visited
	int step[MAX_R][MAX_C] ;
	//地图
	char map[MAX_R][MAX_C];
	//方向,兼职BFS中的顶点的相邻顶点  右 下 左 上
	int dirR[4] = { 1, 0, -1, 0 };
	int dirC[4] = { 0, 1, 0, -1 };
	//传送门开始坐标
	int traR[MAX_R], traC[MAX_C];
	//传送门到达坐标
	int arriveR[MAX_R], arriveC[MAX_C];
	int n, m, num, flag, endFlag = 0;
	//出生点
	int starR, starC;
	//目的地
	int endR, endC;
	int afterMoveR, afterMoveC;
	cin >> n >> m;
	
	for (int i = 0; i<n; ++i)
	{
		for (int j = 0; j<m; ++j)
		{
			cin >> map[i][j];
		}
	}
	
	cin >> num;
	for (int i = 0; i < num; ++i)
	{
		cin >> traR[i] >> traC[i] >> arriveR[i] >> arriveC[i];
	}
		
	
	cin >> starR >> starC >> endR >> endC;
	queue<P> que;

	//初始化步数
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			step[i][j] = 0;
		}
	}
	if (starR == endR&&starC == endC)
	{
		cout << "0" << endl;
	}
	else
	{
		que.push(P(starR, starC));
		while (que.size())
		{
			P p = que.front();
			que.pop();
			flag = 0;

			if (flag == 0)
			{
				for (int i = 0; i<num; ++i)
				{
					if (p.first == traR[i] && p.second == traC[i])
					{
						afterMoveR = arriveR[i];
						afterMoveC = arriveC[i];
						flag = 1;
						step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
						que.push(P(afterMoveR, afterMoveC));
						break;

					}
				}
			}
			if (flag == 0)
			{
				//move
				int i;
				for (i = 0; i<4; ++i)
				{
					afterMoveR = dirR[i]+p.first;
					afterMoveC = dirC[i]+p.second;
					if (afterMoveR >= 0 && afterMoveR<n && afterMoveC >= 0 && afterMoveC<m && map[afterMoveR][afterMoveC] != '1' && step[afterMoveR][afterMoveC] == 0)
					{
						que.push(P(afterMoveR,afterMoveC));
						step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
						if (afterMoveR == endR&&afterMoveC == endC)
						{
							break;
						}

					}
				}
				//判断是否完整走完上个循环
				if (i!=4)
				{
					break;
				}

			}
		}
		if (afterMoveR==endR&&afterMoveC==endC)
		{
			cout << step[endR][endC] << endl;
			return;
		}
		else
		{
			cout << "die" << endl;
			return;
		}

	}
	

	

}
int main()
{
	int count;
	cin >> count;
	while (count--)
	{
		bfs();
	}
	return 0;

}
}

Description
有一个N*M(N,M<=10)的格子迷宫,1代表该格子为墙,不能通过,0代表可以通过,人在迷宫中可以尝试上下左右四个方向移动。
另外,在迷宫中如果从左边走出迷宫会回到迷宫最右边一格(只要该格不是墙),行不变,同样,从右边走出迷宫会
回到迷宫最左边一格,向上走出迷宫会回到迷宫最下边一格,向下走出迷宫会回到迷宫最上边一格。
现在给定一个迷宫,以及起点和终点,问最少多少步可以走出迷宫。如果不能走出迷宫输出“die”。

输入格式
该程序为多CASE,第1行为CASE的数量
每一个CASE,第1行为两个数N(行)和M(列)
然后N行每行M个数,之后是起点坐标和终点坐标sc(行) sr(列) ec(行) er(列)

输出格式
如题

输入样例
2
4 3
011
010
110
110
0 0 3 2
2 2
01
10
0 0 1 1

输出样例
4
die

体会:改变一下map的结构

#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<utility>
#include<cstdio>
using namespace std;
const int MAX_R = 100;
const int MAX_C = 100;
typedef pair<int, int> P;
void bfs()
{
	//步数兼职visited
	int step[MAX_R][MAX_C];
	//地图
	char map[MAX_R][MAX_C];
	//方向,兼职BFS中的顶点的相邻顶点  上 下 左 右
	int dirR[4] = { -1, 1, 0, 0 };
	int dirC[4] = { 0, 0, -1, 1 };

	int n, m, flag;
	//出生点
	int starR, starC;
	//目的地
	int endR, endC;
	int afterMoveR, afterMoveC;
	cin >> n >> m;

	for (int i = 0; i < MAX_R; ++i)
	{
		for (int j = 0; j < MAX_C; j++)
		{
			map[i][j] = '2';
		}
	}

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			cin >> map[i][j];
		}
	}

	cin >> starR >> starC >> endR >> endC;
	queue<P> que;
	starR++;
	starC++;
	endR++;
	endC++;
	//初始化步数
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			step[i][j] = 0;
		}
	}


	if (starR == endR&&starC == endC)
	{
		cout << "0" << endl;
	}
	else
	{
		que.push(P(starR, starC));
		while (que.size())
		{
			P p = que.front();
			que.pop();
			//move
			int i;
			//p.first = 2;
			//p.second = 1;
			for (i = 0; i < 4; ++i)
			{
				afterMoveR = dirR[i] + p.first;
				afterMoveC = dirC[i] + p.second;
				if (i == 0 && map[afterMoveR][afterMoveC] == '2'&&map[n][p.second] == '0'&&step[n][p.second] == 0)
				{
					afterMoveR = n;
					afterMoveC = p.second;
					que.push(P(afterMoveR, afterMoveC));
					step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
					if (afterMoveR == endR&&afterMoveC == endC)
					{
						break;
					}
				}
				if (i == 1 && map[afterMoveR][afterMoveC] == '2'&&map[1][p.second] == '0'&&step[1][p.second] == 0)
				{
					afterMoveR = 1;
					afterMoveC = p.second;
					que.push(P(afterMoveR, afterMoveC));
					step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
					if (afterMoveR == endR&&afterMoveC == endC)
					{
						break;
					}
				}
				if (i == 2 && map[afterMoveR][afterMoveC] == '2'&&map[p.first][m] == '0'&&step[p.first][m] == 0)
				{
					afterMoveR = p.first;
					afterMoveC = m;
					que.push(P(afterMoveR, afterMoveC));
					step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
					if (afterMoveR == endR&&afterMoveC == endC)
					{
						break;
					}
				}
				if (i == 3 && map[afterMoveR][afterMoveC] == '2'&&map[p.first][1] == '0'&&step[p.first][1] == 0)
				{
					afterMoveR = p.first;
					afterMoveC = 1;
					que.push(P(afterMoveR, afterMoveC));
					step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
					if (afterMoveR == endR&&afterMoveC == endC)
					{
						break;
					}
				}

				if (map[afterMoveR][afterMoveC] == '0' && step[afterMoveR][afterMoveC] == 0)
				{
					que.push(P(afterMoveR, afterMoveC));
					step[afterMoveR][afterMoveC] = step[p.first][p.second] + 1;
					if (afterMoveR == endR&&afterMoveC == endC)
					{
						break;
					}

				}
			}
			//判断是否完整走完上个循环
			if (i != 4)
			{
				break;
			}


		}
		if (afterMoveR == endR&&afterMoveC == endC)
		{
			cout << step[endR][endC] << endl;
			return;
		}
		else
		{
			cout << "die" << endl;
			return;
		}

	}




}
int main()
{
	int count;
	cin >> count;
	while (count--)
	{
		bfs();
	}
	getchar();
	getchar();
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值