3.19总结

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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值