题目
思路
要最小时间走出去,就不能向反方向走,所以要走的方向只能出现两种.
一开始我的思路是从遍历过程出发,一段一段看靠近目标坐标的字符数量,但是写出来时间复杂度太高,导致
T
L
E
.
TLE.
TLE.考虑用一重循环来解决这个问题。
用从结果出发的思路,通过分析目标坐标来决定需要向哪个方向走多少次,然后在一次循环遍历中遇到某个方向则自减,直到都归于0则说明可以到达该位置,在循环中判断后及时退出循环,输出答案即可。
代码
正确代码如下:
#include<iostream>
using namespace std;
int main(){
int T,x,y,len;
string s;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&x,&y,&len);
cin>>s;
int ans=-1,i;
int cntU=0,cntD=0,cntL=0,cntR=0;
//要么R要么L 要么U要么D 一定是这样才最快
if(x>0) cntR=x;
else cntL=-x;
if(y>0) cntU=y;
else cntD=-y;
//一重遍历复杂度降到O(n^2)
for(i=0;i<len;i++){
if(cntU==0&&cntD==0&&cntL==0&&cntR==0){
ans=i;//本轮循环结束时 i++,所以这里不用i+1
break;
}
//判大于0是为了让未赋值的方向能保持0值
if(s[i]=='U'&&cntU>0) cntU--;
if(s[i]=='D'&&cntD>0) cntD--;
if(s[i]=='L'&&cntL>0) cntL--;
if(s[i]=='R'&&cntR>0) cntR--;
}
printf("%d\n",ans);
}
return 0;
}
下面是分段重复遍历时复杂度很高的代码 这种方法不可取:
#include<iostream>
#define N 100001
using namespace std;
int main(){
int T,x,y,len;
string s;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&x,&y,&len);
cin>>s;
int ans,i,t,flag=0;
//一段一段统计,复杂度太高了
for(t=0;t<len;t++){
int cntU=0,cntD=0,cntL=0,cntR=0;
for(i=0;i<=t;i++){
if(x>0&&y>0){
if(s[i]=='R') cntR++;
if(s[i]=='U') cntU++;
}
if(x>0&&y<0){
if(s[i]=='R') cntR++;
if(s[i]=='D') cntD++;
}
if(x<0&&y>0){
if(s[i]=='L') cntL++;
if(s[i]=='U') cntU++;
}
if(x<0&&y<0){
if(s[i]=='L') cntL++;
if(s[i]=='D') cntD++;
}
}
if(x>0&&y>0){
if(cntR==x&&cntU==y){
ans=t; flag=1; break;
}else continue;
}
if(x>0&&y<0){
if(cntR==x&&cntD==-y){
ans=t; flag=1; break;
}else continue;
}
if(x<0&&y>0){
if(cntL==-x&&cntU==y){
ans=t; flag=1; break;
}else continue;
}
if(x<0&&y<0){
if(cntL==-x&&cntD==-y){
ans=t; flag=1;
break;
}else continue;
}
}
if(flag) printf("%d\n",ans+1);
else printf("-1\n");
}
return 0;
}
样例输出
2
1 -1 5
LDRDR
3
-2 1 8
RRUDDLRU
-1