2017, X Samara Regional Intercollegiate Programming Contest E. Bonuses and Teleports (思維,模擬)
阿新 • • 發佈:2020-08-14
-
題意:在\(x\)軸上有很多傳送點和鑽石,當位於傳送點上時,可以傳送到其他任意傳送點(不記運算元),位於鑽石上時可以吃掉它,每次可以移動一個單位,問最少多少次可以吃掉所有的鑽石.
-
題解:對於某個位置上的鑽石,我們可以從它左邊的傳送點走過來,或者從它右邊的傳送點走過來,又或者從上一個鑽石的位置直接走過來,我們每次在這三個距離中取最小即可.具體怎麼實現呢?我們首先考慮左右傳送點的情況,遍歷每個鑽石的位置,然後記錄當前這個鑽石到左傳送點或右傳送點的最小距離,之後再次遍歷鑽石位置,比較\(上個鑽石走回傳送門的距離加上從傳送門走到當前鑽石的最小距離\)和\(上個鑽石的位置直接走到當前位置的距離\)
-
程式碼:
int n,m; ll t[N],b[N]; ll c[N]; ll res; int main() { //ios::sync_with_stdio(false);cin.tie(0); scanf("%d %d",&n,&m); for(int i=1;i<=n;++i){ scanf("%lld",&t[i]); } for(int i=1;i<=m;++i){ scanf("%lld",&b[i]); } b[0]=b[m+1]=t[1]; t[n+1]=INF; int j=0; ll tmp; for(int i=1;i<=m;++i){ //求兩個tele之間到鑽石的min while(t[j+1]<=b[i]) j++; if(j==0) c[i]=INF; else c[i]=b[i]-t[j]; if(j<n) tmp=t[j+1]-b[i]; else tmp=INF; c[i]=min(c[i],tmp); } c[0]=c[m+1]=0; for(int i=1;i<=m+1;++i){ ll dis=abs(b[i]-b[i-1]); dis=min(dis,c[i-1]+c[i]); res+=dis; } printf("%lld\n",res); return 0; }