废话不多说,我们先来看题。
我们来分析分析,首先有请萝卜站在'/'面前。
我们发现,萝卜在左边射出了一道朝向为'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;
}