题意:给定长为n的机器人行走路线,每个字符代表上下左右走,可以更改将一些字符改成另外三个字符,定义花费为更改的下标max-min+1,
问从(0,0)走到(X,Y)的最小花费,无解输出-1
n<=2e5,abs(X),abs(Y)<=1e9
思路:第一反应是二分,但其实并没有这个取到等号的严格的性质
不过因为内部可以调整,我们还是可以二分长度,然后看内部调整能不能构造出一组可行解
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 210000 21 #define M 1100 22 #define MOD 2147493647 23 #define eps 1e-8 24 #define pi acos(-1) 25 26 char ch[N]; 27 int s[N][5],n; 28 ll x[N],y[N],X,Y; 29 30 int judge(int s1,int s2,int s3,int s4,int X,int Y) 31 { 32 int tx=s4-s3; 33 int ty=s1-s2; 34 while(tx<X) 35 { 36 if(s3>0&&tx+2<=X) 37 { 38 s3--; s4++; 39 tx+=2; 40 continue; 41 } 42 if(s1>0&&tx+1<=X) 43 { 44 s1--; s4++; 45 ty--; 46 tx++; 47 continue; 48 } 49 if(s2>0&&tx+1<=X) 50 { 51 s2--; s4++; 52 ty++; 53 tx++; 54 continue; 55 } 56 break; 57 } 58 59 while(tx>X) 60 { 61 if(s4>0&&tx-2>=X) 62 { 63 s4--; s3++; 64 tx-=2; 65 continue; 66 } 67 if(s1>0&&tx-1>=X) 68 { 69 s1--; s3++; 70 ty--; 71 tx--; 72 continue; 73 } 74 if(s2>0&&tx-1>=X) 75 { 76 s2--; s3++; 77 ty++; 78 tx--; 79 continue; 80 } 81 break; 82 } 83 if(tx!=X) return 0; 84 if(abs(Y-ty)%2) return 0; 85 return 1; 86 } 87 88 int isok(int len) 89 { 90 for(int i=1;i<=n-len+1;i++) 91 { 92 int j=i+len-1; 93 ll tx=x[i-1]+x[n]-x[j]; 94 ll ty=y[i-1]+y[n]-y[j]; 95 ll t=abs(X-tx)+abs(Y-ty); 96 int s1=s[j][0]-s[i-1][0]; 97 int s2=s[j][1]-s[i-1][1]; 98 int s3=s[j][2]-s[i-1][2]; 99 int s4=s[j][3]-s[i-1][3]; 100 if(t==len||t<len&&judge(s1,s2,s3,s4,X-tx,Y-ty)) return 1; 101 } 102 return 0; 103 } 104 105 int main() 106 { 107 scanf("%d",&n); 108 scanf("%s",ch+1); 109 scanf("%lld%lld",&X,&Y); 110 x[0]=y[0]=0; 111 s[0][0]=s[0][1]=s[0][2]=s[0][3]=0; 112 for(int i=1;i<=n;i++) 113 { 114 x[i]=x[i-1]; 115 y[i]=y[i-1]; 116 for(int j=0;j<=3;j++) s[i][j]=s[i-1][j]; 117 if(ch[i]=='U'){y[i]++; s[i][0]++;} 118 if(ch[i]=='D'){y[i]--; s[i][1]++;} 119 if(ch[i]=='L'){x[i]--; s[i][2]++;} 120 if(ch[i]=='R'){x[i]++; s[i][3]++;} 121 } 122 int l=0; 123 int r=n; 124 int last=n+1; 125 while(l<=r) 126 { 127 int mid=(l+r)>>1; 128 if(isok(mid)){last=mid; r=mid-1;} 129 else l=mid+1; 130 } 131 if(last==n+1) printf("-1 "); 132 else printf("%d ",last); 133 return 0; 134 }