A - Dungeon Master
分析:
- 找到最短逃出地牢的时间,很容易想到BFS
- 这里的地牢有层数,所以可以使用三维数组
- 这题和普通走迷宫的BFS区别就是需要换层,我们只需要多考虑两个方向,也就是去上层或下层
代码:
#include<stdio.h>
struct nb
{
int x;
int y;
int z;
int t;
}g[300000];
int l, r, x, y, z, c, book[31][31][31] = { 0 };
int nx[] = { 0,1,0,-1,0,0 };
int ny[] = { 1,0,-1,0,0,0 };
int nz[] = { 0,0,0,0,1,-1 };
char m[31][31][31];
int main()
{
while (1)
{
int n = 0;
scanf("%d%d%d", &l, &r, &c);
if (l == 0 && r == 0 && c == 0)
break;
for (int i = 0; i < l; i++)
{
for (int j = 0; j < r; j++)
{
for (int k = 0; k < c; k++)
{
scanf(" %c", &m[i][j][k]);
if (m[i][j][k] == 'S')
{
x = j; y = k; z = i;
}
}
}getchar();
}
for (int i = 0; i < l; i++)
{
for (int j = 0; j < r; j++)
{
for (int k = 0; k < c; k++)
{
book[i][j][k] = 0;
}
}
}
int tx, ty, tz, head, tail;
head = tail = 1;
g[tail].x = x;
g[tail].y = y;
g[tail].z = z;
g[tail].t = 0;
tail++;
while (head < tail)
{
for (int i = 0; i < 6; i++)
{
tx = g[head].x + nx[i];
ty = g[head].y + ny[i];
tz = g[head].z + nz[i];
if (tx >= r || tx < 0 || ty >= c || ty < 0 || tz >= l || tz < 0 || book[tz][tx][ty] == 1||m[tz][tx][ty] == '#')
continue;
book[tz][tx][ty] = 1;
g[tail].x = tx;
g[tail].y = ty;
g[tail].z = tz;
g[tail].t = g[head].t + 1;
if (m[tz][tx][ty] == 'E')
{
n = 1;
break;
}
tail++;
}
head++;
if (n == 1)
break;
}
if (n == 1)
printf("Escaped in %d minute(s).\n", g[tail].t);
else
printf("Trapped!\n");
}
return 0;
}
C - Find The Multiple
分析:
- 十进制只包含数字0和1的的数:1、10、11、110、111、1110、1111......;我们可以发现规律这些数总是是它前一个数乘以10或者是+1,而且先是乘以10再是+1,根据规律可递推出这类型的数
- a[i] = a[i / 2] * 10 + i % 2,使用这个式子便可求出这类数,并同时将数对n进行取余,区域结果为0就将其输出,结束查找(如果n=1,直接输出1即可)
代码:
#include <stdio.h>
long long a[1000000];
int main()
{
int n;
while (1)
{
scanf("%d", &n);
if (n == 0)
break;
for (int i = 1;; i++)
{
a[i] = a[i / 2] * 10 + i % 2;
if (a[i] % n == 0)
{
printf("%lld\n", a[i]);
break;
}
}
}
return 0;
}
F - Oil Deposits
分析:
- BFS找连通块(八个方向相连都视为连通)
- 遍历输入的字符串数组,如果遍历到某个字符为‘@’,就使结果+1,然后用BFS进行连通块搜索,搜索到的点就将该点的标记数组book[tx][ty]等于1,就不会重复搜索
代码:
#include<stdio.h>
int nx[] = { 0,1,1,1,0,-1,-1,-1 };
int ny[] = { 1,1,0,-1,-1,-1,0,1 };
struct nb
{
int x;
int y;
}g[10000];
int m, n, book[101][101];
char a[101][101];
int main()
{
int tx, ty, head, tail,ans;
while (1)
{
head = tail = 1;
ans = 0;
scanf("%d%d", &m, &n);
if (m == 0)
break;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
book[i][j] = 0;
for (int i = 0; i < m; i++)
scanf("%s", a[i]);
for(int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
if (a[i][j] == '@' && book[i][j] == 0)
{
g[tail].x = i;
g[tail].y = j;
book[i][j] = 1;
tail++;
ans++;
while (head < tail)
{
for (int k = 0; k < 8; k++)
{
tx = g[head].x + nx[k];
ty = g[head].y + ny[k];
if (tx < 0 || tx >= m || ty < 0 || ty >= n || book[tx][ty] == 1 || a[tx][ty] == '*')
continue;
book[tx][ty] = 1;
g[tail].x =tx;
g[tail].y =ty;
tail++;
}
head++;
}
}
}
printf("%d\n", ans);
}
return 0;
}
G - Find a way
分析:
- BFS
- 使用一个数组存放两人到每个点的最短距离,最后遍历地图,如果遍历到‘@’,就判断vis[i][j]是否等于0(等于0说明走不到该店),不等于0就看其是否为最短距离
代码:
#include<stdio.h>
char f[201][201];
int n, m, book[201][201],vis[201][201], ans;
int nx[] = { 0,1,0,-1 };
int ny[] = { 1,0,-1,0 };
struct nb
{
int x;
int y;
int t;
}g[300000];
void BFS(int a, int b)
{
int flog = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
book[i][j] = 0;
}
int tx, ty, head, tail;
head = tail = 1;
g[tail].x = a;
g[tail].y = b;
g[tail].t = 0;
tail++;
while (head < tail)
{
for (int i = 0; i < 4; i++)
{
tx = g[head].x + nx[i];
ty = g[head].y + ny[i];
if (tx >= n || tx < 0 || ty >=m || ty < 0 || book[tx][ty] == 1 || f[tx][ty] == '#')
continue;
book[tx][ty] = 1;
g[tail].x = tx;
g[tail].y = ty;
g[tail].t = g[head].t + 1;
vis[tx][ty] += g[tail].t;
tail++;
}
head++;
}
}
int main()
{
while (~scanf("%d%d", &n, &m))
{
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
vis[i][j] = 0;
}
int ans = 1e9;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
scanf(" %c", &f[i][j]);
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (f[i][j] == 'Y' || f[i][j] == 'M')
{
BFS(i, j);
}
}
}
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (vis[i][j] != 0 && f[i][j] == '@' && vis[i][j] <= ans)
ans = vis[i][j];
}
printf("%d\n", ans * 11);
}
return 0;
}