题目描述
农夫约翰把他的很多镜子遗落在房子外面,他的奶牛们对这些镜子很好奇,于是奶牛们把这些镜子偷了!
奶牛们把镜子放在了一个N*M的矩阵中,在每个小方格中,他们将镜子按正对角线或者反对角线的方式放置,也就是说镜子的放置形状要么是’/’,要么是’\’。
某一天晚上,奶牛贝里斯拿着一个手电筒站在矩阵的外面,他打开手电筒按水平或者垂直方向朝矩阵内的镜子照射,由于镜子是对角线或者反对角线放置的,所以如果垂直的光过来的话,反射出来的光就是水平的,反之也是同样的道理。贝里斯想要知道他从外面照过来的光最多能被镜子反射几次。
输入
第一行是两个正整数N和M,表示矩阵的大小。
接下里N行,每行M个字符,表示矩阵内镜子放置的情况。字符是’/’或者’\’。
输出
输出一个整数,表示从外面照射进来的一束光最多能在矩阵内被反射的次数,如果会被反射无限次,就输出-1。
样例输入
3 3
/\\
\\\
/\/
样例输出
3
数据范围限制
1<=N,M<=1000。
提示
【样例说明】
贝里斯的光如果从中间列的上方照射的话,将被反射3次。
分析
很简单,对于每一个点,只有8种情况,且不用考虑输出-1的情况。
while在边界内枚举一波就可以了,不会无限循环。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,m,mx,ff,sum;//ff表示现在的光运动的方向
char a[1001][1001];
int main()
{
freopen("mirror.in","r",stdin);
freopen("mirror.out","w",stdout);
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=3;i+=2)
{
for(int j=1;j<=m;j++)
{
ff=i;
sum=0;
/*ff:1=往下,2=往右,3=往上,4=往左*/
int x=1,y=j;
if(i!=1) x=n;
while(x>=1&&y>=1&&x<=n&&y<=m)
{
if(a[x][y]=='/'&&ff==1&&y>=1){y--;ff=4;}
else if(a[x][y]=='/'&&ff==2&&x>=1){x--;ff=3;}
else if(a[x][y]=='/'&&ff==3&&y<=m){y++;ff=2;}
else if(a[x][y]=='/'&&ff==4&&x<=n){x++;ff=1;}
else if (a[x][y]!='/'&&ff==1&&y<=m) y++,ff=2;
else if (a[x][y]!='/'&&ff==2&&x<=n) x++,ff=1;
else if (a[x][y]!='/'&&ff==3&&y>=1) y--,ff=4;
else if (a[x][y]!='/'&&ff==4&&x>=1) x--,ff=3;
sum++;
}
mx=max(sum,mx);
}
}
for(int j=2;j<=4;j+=2)
{
for(int i=1;i<=n;i++)
{
ff=j;
sum=0;
int x=i,y=1;
if(j!=2) y=m;
while(x>=1&&y>=1&&x<=n&&y<=m)
{
if(a[x][y]=='/'&&ff==1&&y>=1){y--;ff=4;}
else if(a[x][y]=='/'&&ff==2&&x>=1){x--;ff=3;}
else if(a[x][y]=='/'&&ff==3&&y<=m){y++;ff=2;}
else if(a[x][y]=='/'&&ff==4&&x<=n){x++;ff=1;}
else if (a[x][y]!='/'&&ff==1&&y<=m) y++,ff=2;
else if (a[x][y]!='/'&&ff==2&&x<=n) x++,ff=1;
else if (a[x][y]!='/'&&ff==3&&y>=1) y--,ff=4;
else if (a[x][y]!='/'&&ff==4&&x>=1) x--,ff=3;
sum++;
}
mx=max(sum,mx);
}
}
cout<<mx;
fclose(stdin);
fclose(stdout);
return 0;
}