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;
}
相关文章
相关标签/搜索