cf.C-Yet Another Walking Robot

题意:

首先介绍下题意,给出字符串的长度。接下来给出字符串,这是一道指令,LRUD分别表示左右上下,起始点在0,0,每次按照指令走,在走的过程中可能会出现走到一个点多次的情况,现在要求你找到可以删除的最短的连续指令,并且不改变重终点的位置,也就是说,删除指令中重复经过一个点两次的最短指令。输出的是要删去的指令的起始位置和结束位置。

思路:

这道题最开始给我的思路是可以使用数字来代替指令,只要判断哪段指令加和可以等于0或者类似的思路即可。但因为是上下左右四个方向,所以这种方法只好pass掉了。接下来就是直接模拟,在读数据的时候就把当下指令执行之后所在点的坐标表示出来,再判断此点是否之前走过就可以了。在实现的时候,第一反应就是用二维数组,但这是行不通的,因为他可能或出现负的坐标,而二维数组是无法记录有负数的位置的,也许这个点会卡到某些菜鸡。如果你了解到c++的话,就会想到用map加pair就可以解决了。
好了,废话不多说,上代码


#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<string>
#include<map> 
using namespace std;
const int N = 1e6+10;
map<pair<int,int>,int> mp;
//前面是点的位置,最近一次走过此点的指令位置
int a[N];
int n , m;
int main()
{
	int n , t;
	string s;
	cin >> t;
	while(t--)
	{
		cin >> n >> s;
		int x=0 , y=0 , l=0 , r=n;
		mp.clear();
		mp[{0,0}]=1;
		//起始位置,也算走过一次,所以赋值为1
		for(int i = 0 ; i < s.size() ; i++)
		{
			if(s[i]=='L')
			  x--;
			else if(s[i]=='R')
			  x++;
			else if(s[i]=='U')
			  y++;
			else
			  y--;
			if(mp[{x,y}]!=0&&r-l>i-mp[{x,y}]+1)
			{
				//如果此点之前走过并且指令的长度比之前储存的长度要短
				l=mp[{x,y}];
				//左边界就是之前的位置
				r=i+1;
				//右边界是i+1,因为l是从1开始,比i大一
			}
			mp[{x,y}]=i+2;
			//i是从0开始的,第一个指令之后应该是第二个,所以可见是i+2
		}
		if(l==0)
		{
			cout << -1 << endl;
		}
		else
		{
			cout << l << ' ' << r << endl;
		}
	}
	return 0;
}
发布了107 篇原创文章 · 获赞 3 · 访问量 7115

猜你喜欢

转载自blog.csdn.net/qq_43504141/article/details/104193625