Codeforces 1296C - Yet Another Walking Robot


題目大意:

給定一個機器人的行走方式

你需要取走一段區間

但要保證取走這段區間后機器人最終到達的終點位置是不變的

問這段區間最短時是哪一段

 

解題思路:

易得,如果重復走到了某些已經走過的點,那么肯定就有一段區間可以被刪除

但是行走次數最大有2e5,即用數組記錄坐標狀態的話起碼要開4e5*4e5的空間,顯然不可能

所以可以用map儲存上一次走到某個坐標是第幾步

那么每次只要判斷當前的坐標是否已經被走過即可,走過的話就嘗試更新答案

因為map中未調用過的int值為0

所以讓原點的步數設置為1防止混淆

初始設置 l=0,r=n+1去最大化這個答案區間,便於第一次判斷得以執行

然后,遍歷這個字符串,如果發現某個點已經走過了,取出這個步數為 d

可以得到 d+1~i 這一段是可以刪除的(d步不可取,因為那一步走完才能到達這個點)

那么就拿 i-(d+1) 和 r-l 作比較,即當 r-l>i-(d+1)  =>  r-l>=i-d 時,更新lr答案

最后把第一步的步數減回去就可以作為答案了(l=0,說明不存在)

 

對於這里的結構體運算符重載,因為使用map需要告知大小關系才能存入這顆紅黑樹進行排序(map是會根據鍵值進行大小排序先的,然后進行二分查找)

所以就重載了小於運算符,先按照x從小到大排,如果x相同按照y從小到大排

這樣就可以在之后二分查找時能夠准確找到值

然后是對等於的重載,在查找的最后需要判斷找到的位置的鍵值和輸入的是否相同(因為如果找不到輸入的鍵值的話是會返回空的——int類型即數值0)

所以要重載等於運算符

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct P{
    int x,y;
    bool operator < (const P& a) const{
        return x<a.x||x==a.x&&y<a.y;
    }
    bool operator == (const P& a) const{
        return x==a.x&&y==a.y;
    }
};
string s;
void solve(){
    int i,n,l,r,d;
    cin>>n>>s;
    map<P,int> mp;
    P pd;
    pd.x=pd.y=0;
    mp[pd]=1;
    l=0;r=n+1;//先最大化答案區間
    s="  "+s;//下標向右移動2位,便於直接把i當作步數
    for(i=2,n++;i<=n;i++){
        if(s[i]=='L')
            pd.x--;
        else if(s[i]=='R')
            pd.x++;
        else if(s[i]=='U')
            pd.y++;
        else
            pd.y--;
        d=mp[pd];
        if(d>0){//這個點走過
            if(r-l>=i-d)
                l=d+1,r=i;
        }
        mp[pd]=i;
    }
    if(l==0)
        cout<<"-1\n";
    else
        cout<<l-1<<' '<<r-1<<'\n';//因為原點步數為1,把差值減回去
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;while(T--)
        solve();
    
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM