gym101102I Simple Robot(思路)

題意:ios

給你一個地圖的大小(1e5*1e5)和操做次數(2e5),每次操做使機器人上下左右移動,若是當前在邊界還要向外走,機器人就會忽略當前操做,spa

要求你給出一個起點,使得被忽略的操做數最少,輸出最少的忽略次數。code

思路:blog

這個題真思路。。首先,上下和左右是徹底獨立的。string

開始我想的是用線段樹維護一個相對起點的位置(維護最值),而後能夠logn找到距離當前位置距離爲地圖大小的下一個操做點,it

而後nlogn預處理出全部的,而後dfs枚舉當前撞兩邊的牆和還在走的座標,過程能夠記憶化,經過預處理,這個複雜度是on的,io

而後就獲得了最小的忽略次數,根據對應的是沒撞牆或者撞牆的操做點,能夠獲得起始座標。class

可是看了幾分別人的代碼。。大致意思就是對於上下或左右,你最多減小的次數就是地圖的長度,你能夠默認當前在最上邊,而後去模擬整個過程,stream

一旦撞到了上牆,起點位置就向下移動一個,撞下牆就表示下面的起點向上移一個,不過不用管,能夠讓撞了地圖長度次牆就結束,map

表示已經避免了最大的撞牆次數了,起點位置已經固定。若是沒有撞牆,那就在最上邊就行了。。

左右徹底相同的思路再寫一遍,而後獲得了起點的座標,模擬一下整個過程就獲得了最小次數了。

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <time.h>
#include <cmath>
#include <stdlib.h>
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define pii pair<int,int>
#define mkp make_pair
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int inf=0x3f3f3f3f;
const LL INF=0x7f7f7f7f;
const int mod=1e9+7;
const int N=2e5+10;
int t,n,m;
char s[N];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%s",&n,&m,s);
        int len=strlen(s),x=1,y=1,l=1,r=n,ans=0;
        for(int i=0;i<len;i++)
        {
            if(l==r) break;
            if(s[i]=='^')
            {
                if(l==1) x++;
                else l--;
                r--;
            }
            else if(s[i]=='v')
            {
                l++;
                if(r<n) r++;
            }
        }
        l=1,r=m;
        for(int i=0;i<len;i++)
        {
            if(l==r) break;
            if(s[i]=='<')
            {
                if(l==1) y++;
                else l--;
                r--;
            }
            else if(s[i]=='>')
            {
                l++;
                if(r<m) r++;
            }
        }
        for(int i=0;i<len;i++)
        {
            if(s[i]=='^')
            {
                if(x==1) ans++;
                else x--;
            }
            else if(s[i]=='v')
            {
                if(x==n) ans++;
                else x++;
            }
            else if(s[i]=='<')
            {
                if(y==1) ans++;
                else y--;
            }
            else if(s[i]=='>')
            {
                if(y==m) ans++;
                else y++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
相關文章
相關標籤/搜索