题意:

给你一个地图的大小(1e5*1e5)和操作次数(2e5),每次操作使机器人上下左右移动,如果当前在边界还要向外走,机器人就会忽略当前操作,

要求你给出一个起点,使得被忽略的操作数最少,输出最少的忽略次数。

思路:

这个题真思路。。首先,上下和左右是完全独立的。

开始我想的是用线段树维护一个相对起点的位置(维护最值),然后可以logn找到距离当前位置距离为地图大小的下一个操作点,

然后nlogn预处理出所有的,然后dfs枚举当前撞两边的墙和还在走的坐标,过程可以记忆化,通过预处理,这个复杂度是on的,

然后就得到了最小的忽略次数,根据对应的是没撞墙或者撞墙的操作点,可以得到起始坐标。

但是看了几分别人的代码。。大体意思就是对于上下或左右,你最多减少的次数就是地图的长度,你可以默认当前在最上边,然后去模拟整个过程,

一旦撞到了上墙,起点位置就向下移动一个,撞下墙就表示下面的起点向上移一个,不过不用管,可以让撞了地图长度次墙就结束,

表示已经避免了最大的撞墙次数了,起点位置已经固定。如果没有撞墙,那就在最上边就好了。。

左右完全相同的思路再写一遍,然后得到了起点的坐标,模拟一下整个过程就得到了最小次数了。

/* ***********************************************
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;
}