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;
}