1. 程式人生 > 其它 >1607F - Robot on the Board 2 - Codeforces

1607F - Robot on the Board 2 - Codeforces

Problem - 1607F - Codeforces

題目大意:

​ 有一個n*m的矩形地圖,每個點有RLUD,表示在該點下一步走個方向,走出地圖或者走到走過的點機器人就會損毀。問從哪個點開始走能走最長的路徑。

思路:

​ 對於每一個點他之後的路徑都是確定的,所以可以通過記憶化(設定dp陣列)來降低時間複雜度。值得注意的是環的處理

​ 出現環時,需要把整個環裡的每個節點設定成環的周長。因為不論從哪個點進入該環,他最多就只能沿著環走一圈。

​ 還有就是注意不能開ll。開ll就mle。卡了好久

程式碼:

#define show2(a , n , m) for(int i = 1 ; i <= n ; i ++ , cout << "\n")for(int j = 1 ; j <= m ; cout << a[i][j ++ ] << " " )
#define get2(a , n , m) for(int i = 1 ; i <= n ; i ++ )for(int j = 1 ; j <= m ; j ++ ) cin >> a[i][j] ;
#define show1(a , n) for(int i = 1 ; i <= n ; i ++ ) cout << a[i] << " "; cout << "\n" ;
#define get1(a , n) for(int i = 1 ; i <= n ; i ++ ) cin >> a[i] ;
#define pll pair< long long , long long >
#define pii pair< int , int >
#define debug cout<<"= =\n"
#include<bits/stdc++.h>
#define YES puts("YES")  
#define NO puts("NO")  
#define se second
#define fi first 
 
using namespace std ;
typedef int ll ;//<============================這裡把ll定義成int了,後面所有ll都是int
const ll mod = 1e9 + 7 ;
const ll N = 2e3 + 5 ;
const ll INF = 0x3f3f3f3f ;

char s[N][N] ;
ll dp[N][N] ;
bool vis[N][N] ;
pll rec[N * N] ;
ll cnt , n , m ;

ll dfs(ll i , ll j){//cout << i << " " << j << "\n" ;
	rec[ ++ cnt ] = {i , j} ;//記錄路徑
	if(i > n || i < 1 || j > m || j < 1 || dp[i][j] || vis[i][j])return dp[i][j] ;
	vis[i][j] = 1 ;
	if(s[i][j] == 'D')return dp[i][j] = 1 + dfs(i + 1 , j) ;
	if(s[i][j] == 'U')return dp[i][j] = 1 + dfs(i - 1 , j) ;
	if(s[i][j] == 'R')return dp[i][j] = 1 + dfs(i , j + 1) ;
	if(s[i][j] == 'L')return dp[i][j] = 1 + dfs(i , j - 1) ;
	
}

void solve(){
	ll ans = 0 , I , J ;
	cin >> n >> m ;
	get2(s , n , m) ;
	for(int i = 1 ; i <= n + 1 ; i ++ )
	for(int j = 1 ; j <= m + 1 ; j ++ ) dp[i][j] = vis[i][j] = 0 ;
	
	for(int i = 1 ; i <= n ; i ++ )
	for(int j = 1 ; j <= m ; j ++ ){
		cnt = 0 ;
		ll tmp = dfs(i , j) ;
		if(tmp > ans){
			ans = tmp ; I = i , J = j ;
		}
		pll t = rec[cnt] ;//判判斷該路徑中有沒有出現環
		for(int k = 1 ; k < cnt ; k ++ ){
			if(rec[k] == t){//出現環(首尾相同) 
				ll len = k ;
				while(k <= cnt) dp[rec[k].fi][rec[k].se] = cnt - len , k ++ ;
			}//cnt - len是環周長
		}
	}
	
	cout << I << " " << J << " " << ans << "\n" ;
}

int main(){
	ios::sync_with_stdio(false) ;
	cin.tie(0) ; cout.tie(0) ;
	
	ll T ; cin >> T ;
	while(T -- ) solve() ;
	
}