CF1296C Yet Another Walking Robot 题解

题目:Link

一道较简单的思维题,实现过程很简单,主要是怎样想到做法

对于此题,只能用减少走动操作的方式来优化路线,并不能用短路经替换长路径。这样,就只剩下了一个优化方法,消环

对于每一步访问的坐标,我们就在 v i s vis 数组中标记上访问的时间。当走到一个已被访问过的坐标 ( x , y ) (x,y) 时,我们就找到了一个环。而要想消掉这个环所要删除的操作就是区间 [ v i s ( x , y ) + 1 , i ] [vis_{(x,y)}+1,i] 内的所有操作,最后更新答案即可
由于要求的是最小环, v i s vis 数组储存的应该是每个坐标上一次(最近一次)被访问的时间

#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
const int Maxn=200000+10,inf=0x3f3f3f3f;
int n,l,r;
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
inline void move(char opt,int &x,int &y)
{
	if(opt=='L')--x;
	if(opt=='R')++x;
	if(opt=='U')++y;
	if(opt=='D')--y;
}
int main()
{
//	freopen("in.txt","r",stdin);
	int T=read();
	while(T--)
	{
		n=read();
		int ans=inf;
		char s[Maxn];
		map <pair<int,int>,int> vis;
		
		vis[make_pair(0,0)]=0; // 刚开始在原点
		int x=0,y=0;
		scanf("%s",s+1);
		for(int i=1;i<=n;++i)
		{
			move(s[i],x,y);
			pair <int,int> cur=make_pair(x,y);			
			if(vis[cur] || !x && !y) // 该点已被访问过得情况
			{
				if(i-vis[cur]<ans) // 更新答案
				{
					ans=i-vis[cur];
					l=vis[cur]+1,r=i;
				}
			}
			vis[cur]=i;
		}
		if(ans==inf)puts("-1");
		else printf("%d %d\n",l,r);
	}
	return 0;
}
发布了75 篇原创文章 · 获赞 2 · 访问量 1766

猜你喜欢

转载自blog.csdn.net/Brian_Pan_/article/details/104495008