【CF1073C】Vasya and Robot(二分,构造)

题意:给定长为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\n");
132      else printf("%d\n",last);
133     return 0;
134 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/9853793.html