[codeforces 1296C] Yet Another Walking Robot 三重排序+全网唯一的代码/STL中map+pair/类hash算法

[codeforces 1296C] Yet Another Walking Robot 三重排序+全网唯一的代码/STL中map+pair/类hash算法

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1296/problem/C

方法一:三重排序+全网唯一的代码

ProblemLangVerdictTimeMemory
C - Yet Another Walking Robot GNU C++11Accepted46 ms2400 KB

//找环
/*
This optimization is a low-budget project so you need to remove the shortest possible non-empty substring to optimize the robot's path such that the endpoint of his path doesn't change.
上句中的he shortest possible non-empty substring尤为关键,删除最短的。
英文实力还需加强。
*/

#include <cstdio>
#include <algorithm>
#define maxn 200010
using namespace std;
struct node{
	int seq,x,y;//seq访问顺序;x,y坐标
}p[maxn];
char s[maxn];
int cmp(node a,node b){//三重排序
	return a.x==b.x?(a.y==b.y?a.seq<b.seq:a.y<b.y):a.x<b.x;
}
int main(){
	int t,n,l,r,i;
	scanf("%d",&t);
	while(t--){
		scanf("%d%s",&n,s+1);
		p[0].seq=0,p[0].x=0,p[0].y=0,l=0,r=n;//初始化
		for(i=1;i<=n;i++)
			if(s[i]=='L')p[i].seq=i,p[i].x=p[i-1].x-1,p[i].y=p[i-1].y;
			else if(s[i]=='R')p[i].seq=i,p[i].x=p[i-1].x+1,p[i].y=p[i-1].y;
			else if(s[i]=='U')p[i].seq=i,p[i].x=p[i-1].x,p[i].y=p[i-1].y+1;
			else if(s[i]=='D')p[i].seq=i,p[i].x=p[i-1].x,p[i].y=p[i-1].y-1;
		sort(p+0,p+n+1,cmp);//范了一个很大的错误,此处错写成sort(p+0,p+0+n,cmp);查了1个小时,请注意sort是左闭右开函数.
		for(i=1;i<=n;i++){
			if(p[i].x==p[i-1].x&&p[i].y==p[i-1].y)//起点终点是同一个点
				if(p[i].seq-(p[i-1].seq+1)<r-l)l=p[i-1].seq+1,r=p[i].seq;//取最小值
		}
		if(r-l==n)printf("-1\n");//数据一直未更新l=0,r=n
		else printf("%d %d\n",l,r);
	}
	return 0;
}

方法二:STL中map+pair

ProblemLangVerdictTimeMemory
C - Yet Another Walking Robot GNU C++11Accepted46 ms8000 KB

//STL中map+pair
思路同https://www.cnblogs.com/pixel-Teee/p/12272446.html
我们可以使用关联数组map,存储走过的路径的坐标到字符串下标的映射,我们只要走过的坐标点曾经出现过,说明我们走了一段徒劳的路径,那么我们就更新最小的区间的两端。 

#include <cstdio>
#include <map>
using namespace std;
char s[200010];
map< pair<int,int>,int > mp;
pair<int,int> p;
int main(){
	int t,n,i,l,r;
	scanf("%d",&t);
	while(t--){
		scanf("%d%s",&n,s+1);
		mp.clear();//别忘了初始化
		p.first=0,p.second=0,mp[p]=0,l=0,r=n;
		for(i=1;i<=n;i++){
			if(s[i]=='L')--p.first;
			else if(s[i]=='R')++p.first;
			else if(s[i]=='U')++p.second;
			else if(s[i]=='D')--p.second;
			if(mp.count(p))//mp中已存p值为1,未存p值为0
				if(i-(mp[p]+1)<r-l)l=mp[p]+1,r=i;//找最小值
			mp[p]=i;
		}
		if(r-l==n)printf("-1\n");//n-0==n
		else printf("%d %d\n",l,r);
	}
	return 0;
}

方法三:类hash算法

ProblemLangVerdictTimeMemory
C - Yet Another Walking Robot GNU C++11Accepted61 ms8100 KB

//类hash算法
//想过但没有实现
//思路同https://blog.csdn.net/qq_37504214/article/details/104195791
/*
'L' -1;'R' +1;'U' +200007;'D' -200007

200007*200000=4*10^10 int溢出,需用long long
*/
//map查重真是个好帮手。

#include <cstdio>
#include <map>
#define L -1
#define R 1
#define U 200007
#define D -200007
#define LL long long 
using namespace std;
char s[200010];
map<LL,int> mp;
int main(){
	int t,i,n,l,r;
	LL p;
	scanf("%d",&t);
	while(t--){
		scanf("%d%s",&n,s+1);
		mp.clear(),p=0,mp[0]=0,l=0,r=n;
		for(i=1;i<=n;i++){
			if(s[i]=='L')p+=L;
			else if(s[i]=='R')p+=R;
			else if(s[i]=='U')p+=U;
			else if(s[i]=='D')p+=D;
			if(mp.count(p))
				if(i-(mp[p]+1)<r-l)l=mp[p]+1,r=i;
			mp[p]=i;
		}
		if(r-l==n)printf("-1\n");
		else printf("%d %d\n",l,r);
	}
	return 0;
}

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值