搜索入门题解

E题,

题意为y和m要去肯德基聚餐,图中有多个kfc,他们要选的那个kfc必须到彼此的所用时间之和最小,问 最少需要多少时间(这里一格代表了11分钟),将y到每点的时间和m到每点的时间用bfs打表,打好表后扫地图,如果扫到@的话算下时间之和,更新min。y不能经过m的出发点,m也不能经过y的出发点

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
char map[210][210];
int a[210][210];
int b[210][210];
//int vis[210][210];
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
int n, m, kfc, yx, yy, mx, my;
bool flag = true;
struct node
{
	int x, y;
};

void bfs(int x, int y,int vis[210][210])
{
	vis[x][y] = 0;
	queue<node>qu;
	node p, q;
	p.x = x; p.y = y;
	qu.push(p);
	while (!qu.empty())
	{
		q = qu.front();
		qu.pop();
		for (int i = 0; i < 4; i++)
		{
			p.x = q.x + dx[i];
			p.y = q.y + dy[i];
			if (p.x >= 0 && p.x < n&&p.y >= 0 && p.y < m&&!vis[p.x][p.y] && map[p.x][p.y] != '#')
			{
				vis[p.x][p.y] = vis[q.x][q.y] + 1;
				qu.push(p);
			}
		}
	}
}

int main()
{
	while (cin >> n >> m)
	{
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		//memset(map, '#', sizeof(map));
		kfc = 0;
		for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			cin >> map[i][j];
			if (map[i][j] == 'Y')
			{
				yx = i; yy = j;
			}
			else if (map[i][j] == 'M')
			{
				mx = i; my = j;
			}
		}
		bfs(yx, yy,a);
		bfs(mx, my,b);
		int minn = inf;
		for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			if (map[i][j] == '@'&&a[i][j]!=0)
				minn = min(minn, a[i][j] + b[i][j]);
		}
		cout << 11 * minn << endl;
	}
	return 0;
}

F 题

一维BFS从N到K ,最少需要多少步,三种移动方式加1,减1,乘2;

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int a[100010],b[100010];
int n,k;
queue<int>qu;
int bfs()
{
    int x,y,ans=0;
    qu.push(n);
    a[n]=1;
    while(!qu.empty())
    {
        x=qu.front();
        if(x==k)
            return b[x];
        qu.pop();
        if(x+1<=100000&&a[x+1]==0)
        {
            a[x+1]=1;
            b[x+1]=b[x]+1;
            qu.push(x+1);
        }
        if(x-1>=0&&a[x-1]==0)
        {
            a[x-1]=1;
            b[x-1]=b[x]+1;
            qu.push(x-1);
        }
        if(x*2<=100000&&a[x*2]==0)
        {
            a[x*2]=1;
            b[x*2]=b[x]+1;
            qu.push(x*2);
        }
    }
}
int main()
{
    while(cin>>n>>k)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        cout<<bfs()<<endl;
    }
    return 0;
}

G题

给出骑士的骑士位置和目标位置,计算骑士要走多少步。首先要做这道题必须要理解国际象棋中骑士的走法,国际象棋中,骑士是在一个3*2的格子中进行对角线移动,通过画图很容易就知道骑士最多可以朝八个方向移动,那么就朝8个方向进行BFS即可

代码:

#include<iostream>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int a[8][2] = { 1, 2, 2, 1, 2, -1, 1, -2, -1, -2, -2, -1, -2, 1, -1, 2 };
char s1[2], s2[2];
int  x1, x2, k[10][10];
struct node
{
	int x, y, step;
};

int bfs()
{
	queue<node>q;
	node m, n, p;
	m.x = s1[0] - 'a' + 1;
	m.y = s1[1] - '0';
	m.step = 0;
	q.push(m);
	x1 = s2[0] - 'a' + 1;
	x2 = s2[1] - '0';
	while (!q.empty())
	{
		n = q.front();
		q.pop();
		if (n.x == x1&&n.y == x2)
			return n.step;
		for (int i = 0; i < 8; i++)
		{
			p.x = n.x + a[i][0];
			p.y = n.y + a[i][1];
			if (p.x<1 || p.x>8 || p.y>8 || p.y < 1 || k[p.x][p.y] == 1)
				continue;
			p.step = n.step + 1;
			k[p.x][p.y] = 1;
			if (p.x == x1&&p.y == x2)
				return p.step;
			q.push(p);
		}
	}
	return 0;
}

int main()
{
	while (scanf("%s%s",s1,s2)!=EOF)
	{
		memset(k, 0, sizeof(k));
		printf("To get from %s to %s takes %d knight moves.\n", s1, s2, bfs());
	}
	return 0;
}

H题

题意中文不说了,坑点:遇到上下两层都是# 的,就把上下两层的这个位置都弄成墙就行,还有遇到 一层是#一层是墙的。也直接把俩都弄城墙就行,否则要判断他撞死,但不过代码并没有这样。就是遇到#的时候,加步数,虽然上下楼不用时间。但是你走到#需要一步的时间。
 

代码:

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
char map[2][20][20];
int vis[2][15][15], p[3], s[3];
int t, n, m, lim;
int dic[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
struct node
{
	int x, y, floor;
	int step;
};

int c(int floor, int x, int y)
{
	if (x < 0 || x >= n || y < 0 || y >= m)
		return 1;
	if (map[floor][x][y] == '*')
		return 1;
	return 0;
}

void bfs()
{
	memset(vis, 0, sizeof(vis));
	node a, next;
	queue<node>qu;
	int i, j, k;
	a.floor = s[0]; a.x = s[1]; a.y = s[2];
	a.step = 0;
	vis[s[0]][s[1]][s[2]] = 1;
	qu.push(a);
	while (!qu.empty())
	{
		a = qu.front();
		if (a.floor == p[0] && a.x == p[1] && a.y == p[2])
			printf("YES\n");
		qu.pop();
		if (a.step >= lim)
			break;
		for (i = 0; i < 4; i++)
		{
			next = a;
			next.x += dic[i][0];
			next.y += dic[i][1];
			next.step++;
			if (c(next.floor, next.x, next.y))
				continue;
			if (vis[next.floor][next.x][next.y])
				continue;
			vis[next.floor][next.x][next.y] = 1;
			if (map[next.floor][next.x][next.y] == '#')
			{
				next.floor = 1 - next.floor;
				if (c(next.floor, next.x, next.y))
					continue;
				if (vis[next.floor][next.x][next.y])
					continue;
				if (map[next.floor][next.x][next.y] == '*' || map[next.floor][next.x][next.y] == '#')
					continue;
				vis[next.floor][next.x][next.y] = 1;
			}
			if (next.floor == p[0] && next.x == p[1] && next.y == p[2])
			{
				printf("YES\n");
				return;
			}
			qu.push(next);
		}
	}
	printf("NO\n");
}

int main()
{
	int i, j, k;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d %d %d", &n, &m, &lim);
		for (k = 0; k < 2; k++)
		{
			for (i = 0; i < n; i++)
			{
				scanf("%s", map[k][i]);
				for (j = 0; j < m; j++)
				{
					if (map[k][i][j] == 'S')
					{
						s[0] = k; s[1] = i; s[2] = j;
					}
					if (map[k][i][j] == 'P')
					{
						p[0] = k; p[1] = i; p[2] = j;
					}
				}
			}
		}
		bfs();
	}
	return 0;
}

贴上处理过遇到上下两层都是# 的,还有遇到 一层是#一层是墙的代码

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
char mp[2][20][20];
int vis[2][20][20], p[3], s[3];
int t, n, m, lim;
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { -1, 1, 0, 0 };
struct node
{
	int x, y, floor;
	int step;
};
int judge(int floor, int x, int y)
{
	if (x < 0 || x >= n || y < 0 || y >= m)
		return 1;
	if (mp[floor][x][y] == '*')
		return 1;
	if (vis[floor][x][y])
		return 1;
	return 0;
}
void bfs()
{
	queue<node>qu;
	memset(vis, 0, sizeof(vis));
	node now, next;
	now.floor = s[0], now.x = s[1], now.y = s[2];
	vis[s[0]][s[1]][s[2]] = 1;
	now.step = 0;
	qu.push(now);
	while (!qu.empty())
	{
		now = qu.front();
		if (now.floor == p[0] && now.x == p[1] && now.y == p[2])
		{
			if (now.step <= lim)
				puts("YES");
			else
				puts("NO");
			return;
		}
		qu.pop();
		for (int i = 0; i < 4; i++)
		{
			next.floor = now.floor;
			next.x = now.x + dx[i];
			next.y = now.y + dy[i];
			next.step = now.step + 1;
			if (judge(next.floor, next.x, next.y))
				continue;
			vis[next.floor][next.x][next.y] = 1;
			if (mp[next.floor][next.x][next.y] == '#')
			{
				next.floor ^= 1;
				vis[next.floor][next.x][next.y] = 1;
			}
			qu.push(next);
		}
	}
	puts("NO");
	return;
}

int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n >> m >> lim;
		for (int i = 0; i < 2; i++)
		{
			for (int j = 0; j < n; j++)
			{
				cin >> mp[i][j];
			}
		}
		for (int i = 0; i < 2; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < m; k++)
				{
					if (mp[i][j][k] == 'P')
						p[0] = i, p[1] = j, p[2] = k;
					if (mp[i][j][k] == 'S')
						s[0] = i, s[1] = j, s[2] = k;
					if (mp[i][j][k] == '#')
					{
						if (mp[i ^ 1][j][k] == '#' || mp[i ^ 1][j][k] == '*')
							mp[i][j][k] = '*', mp[i ^ 1][j][k] = '*';
					}
				}
			}
		}
		bfs();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/KXL5180/article/details/86593282