AcWing 1929. 镜子田地(DFS)

题面连接

https://www.acwing.com/problem/content/description/1931/

思路

因为光路可逆,那么对于每一个点的方向就是固定的,也就是入射角和反射角,那么对于每一个点的走向我们都是可以提前预知的,所以我们直接对每个外圈点进行DFS搜索即可,只不过需要注意一点我们要有一个变量d来表示朝向,因为光在不同的方向入射,那么其出射方向也不同,我们这里用0表示向上、1表示向右、2表示向下、3表示向左,那么我们会发现,如果下一个点是 '/'的话

  • 入射方向是0那么出射方向就会变成1
  • 入射方向是1那么出射方向就会变成0
  • 入射方向是2那么出射方向就会变成3
  • 入射方向是3那么出射方向就会变成2

那么对于另一种镜子也就同理了,所以直接对外圈的每一个点DFS就好了

代码

#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

ll ksm(ll a,ll b) {
	ll ans = 1;
	for(;b;b>>=1LL) {
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	}
	return ans;
}

ll lowbit(ll x){return -x & x;}

const int N = 1e3+10;
//----------------自定义部分----------------
int n,m,q,a[N];
char mp[N][N];

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

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	cin>>n>>m;
	getchar();
	for(int i = 0;i < n; ++i) {
		cin>>mp[i];
	}
	for(int i = 0;i < n; ++i) {
		cout<<mp[i]<<endl;
	}
	int ans = 0;
	for(int i = 0;i < n; ++i) {
		ans = max(dfs(i,0,1),ans);
		ans = max(dfs(i,m-1,3),ans);
	}
	for(int i = 0;i < m; ++i) {
		ans = max(dfs(0,i,2),ans);
		ans = max(dfs(n-1,i,0),ans);
	}
	cout<<ans<<endl;
	return 0;
}
上一篇:AcWing 1904. 奶牛慢跑(单调栈)


下一篇:计数问题