1929:镜子田地

废话不多说,我们先来看题。

 

 

我们来分析分析,首先有请萝卜站在'/'面前。

 

 我们发现,萝卜在左边射出了一道朝向为'1'的光,光触碰到了镜子,朝向转变为'0'了。

那是不是萝卜对'/'镜子进行折射时,总会得到"朝向^=1"的光束呢?我们请萝卜再从四面八方射出光线。

 我们发现,无论萝卜从哪里射出光线,都会得到"朝向^=1"的光束。

那如果萝卜面前是'\'呢?我们再请萝卜站在'\'面前。

 我们发现,萝卜向'1'方向射出了一条光线,碰到镜子并折射出了一条朝向为'2'的光线。那是不是所有碰到'\'的光线都会折射出一条朝向为"朝向^=3"的光线呢?

我们请萝卜从四面八方射出光线。

我们发现,无论萝卜从哪里射出光线,最终折射出的都是"朝向^=3"的光线。

想到这里,我们就可以开始编代码了。

首先是存储。

int n, m, ans;
int dx[5] = {-1, 0, 1, 0}, dy[5] = {0, 1, 0, -1};
char c[1005][1005];

然后就是平平无奇的输入。

scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
    scanf("%s", c[i] + 1);

接下来我们就应该对每种可能进行遍历了。

for (int i = 1; i <= n; i++)
    ans = max(max(ans, dfs(i, 1, 1)), dfs(i, m, 3));

这个代码的意思是,奶牛在(i,1)位置上 ,射出了一条朝向为'1'的光线,所能折射的最大次数和奶牛在(i,m)位置上,射出了一条朝向为'3'的光线,所能折射的最大次数的最大值。

for (int i = 1; i <= m; i++)
    ans = max(max(ans, dfs(1, i, 2)), dfs(n, i, 0));

然后我们枚举奶牛在(1,i)的位置上,射出了一条朝向为'2'的光线,所能折射的最大次数和奶牛在(n,i)位置上,射出了一条朝向为'4'的光线,所能折射的最大次数的最大值。

然后是输出。

printf("%d", ans);

最后,我们来编写dfs函数。

int dfs(int x, int y, int d)
{
    if (x < 1 || y < 1 || x > n || y > m)
        return 0;
    if (c[x][y] == '/')
        d ^= 1;
    else
        d ^= 3;
    return dfs(x + dx[d], y + dy[d], d) + 1;
}

 到这里我们把代码段组合一下,得到最终的代码。

#include <bits/stdc++.h> // 万能头文件
using namespace std;
int n, m, ans;
int dx[5] = {-1, 0, 1, 0}, dy[5] = {0, 1, 0, -1};
char c[1005][1005];
int dfs(int x, int y, int d)
{
    if (x < 1 || y < 1 || x > n || y > m) // 如果枚举出界了,结束枚举
        return 0;
    if (c[x][y] == '/')
        d ^= 1; // 计算反射角度
    else
        d ^= 3; // 计算反射角度
    return dfs(x + dx[d], y + dy[d], d) + 1; // 进行新一轮搜索
}
int main()
{
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%s", c[i] + 1);
    for (int i = 1; i <= n; i++) // 枚举从右到左(横向)激光和从左到右(横向)激光
        ans = max(max(ans, dfs(i, 1, 1)), dfs(i, m, 3));
    for (int i = 1; i <= m; i++) // 枚举从上到下(竖向)激光和从下到上(竖向)激光
    	ans = max(max(ans, dfs(1, i, 2)), dfs(n, i, 0));
    printf("%d", ans);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值