Vasya and Robot CodeForces - 1073C (經典走方格問題+二分)
阿新 • • 發佈:2018-11-08
題意:機器人從起點(0,0)開始,每次只能向上,下,左,右進行移動,給出一個移動序列,問你通過修改這個移動序列,可以讓機器人走到(x,y)點的最小修改量(最小修改量定義為:修改的最大編號-最小編號+1)。
思路:將能否走到(x,y)轉化為偏移量能否從 0到 x,0到y.
我們先模擬一下他給出的移動序列,記錄這個序列產生偏移量的字首和,有了字首和,我們就可以知道任意區間對結果的偏移量貢獻。
下面我們列舉修改長度:它的意思是,我們選取的那個區間,可以隨意改動,因為我們只關心這個區間的起點和終點,具體內部如果變化,我們並不關心。
列舉長度使用2分來做,在check()函式裡,我們計算出除去這個區間以後,已經走的偏移量,再看這個區間的長度能否滿足還需要的偏移量。
還有一個問題是,如果列舉的區間長度大於所需的,那麼超出部分一定是偶數,這是走方格問題的一個性質。
程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+7; int n; int sx[maxn],sy[maxn]; int x,y; bool check(int len) { for(int i=1;i+len<=n+1;i++) { int tmpx=x,tmpy=y; int subx=sx[n]-sx[i+len-1];//最後幾步走的,先減回來 int suby=sy[n]-sy[i+len-1]; tmpx-=subx;//前面走的 tmpy-=suby; int addx=sx[i-1]-sx[0];//還需要的 int addy=sy[i-1]-sy[0]; if(abs(tmpx-addx)+abs(tmpy-addy)<=len&&(len-abs(tmpx-addx)-abs(tmpy-addy))%2==0) { return 1; } } return false; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif scanf("%d",&n); string s; cin>>s; scanf("%d%d",&x,&y); sx[0]=0,sy[0]=0; for(int i=0;i<n;i++) { if(s[i]=='U') { sy[i+1]=sy[i]+1; sx[i+1]=sx[i]; } else if(s[i]=='D') { sy[i+1]=sy[i]-1; sx[i+1]=sx[i]; } else if(s[i]=='R') { sx[i+1]=sx[i]+1; sy[i+1]=sy[i]; } else if(s[i]=='L') { sx[i+1]=sx[i]-1; sy[i+1]=sy[i]; } } int l=0,r=n; int ans=-1; while(l<=r) { int mid=(l+r)>>1; if(check(mid)) { r=mid-1; ans=mid; } else { l=mid+1; } } printf("%d\n",ans); return 0; }