1. 程式人生 > 其它 >掃地機器人(第十屆藍橋杯研究生組)

掃地機器人(第十屆藍橋杯研究生組)

題目:

小明公司的辦公區有一條長長的走廊,由 N 個方格區域組成,如下圖所示。

走廊內部署了 K 臺掃地機器人,其中第 ii 臺在第 Ai 個方格區域中。

已知掃地機器人每分鐘可以移動到左右相鄰的方格中,並將該區域清掃乾淨。

請你編寫一個程式,計算每臺機器人的清掃路線,使得

  1. 它們最終都返回出發方格,
  2. 每個方格區域都至少被清掃一遍,
  3. 從機器人開始行動到最後一臺機器人歸位花費的時間最少。

注意多臺機器人可以同時清掃同一方塊區域,它們不會互相影響。

輸出最少花費的時間。

在上圖所示的例子中,最少花費時間是 66。

第一臺路線:2−1−2−3−4−3−2,清掃了 1、2、3、4 號區域。

第二臺路線 5−6−7−6−5,清掃了 5、6、7。

第三臺路線 10−9−8−9−10,清掃了 8、9和 10。

輸入格式

第一行包含兩個整數 N 和 K。

接下來 K 行,每行一個整數 Ai。

輸出格式

輸出一個整數表示答案。

資料範圍

1≤K<N≤1e5,
1≤Ai≤N

輸入樣例:

10 3
5
2
10

輸出樣例:

6

分析思路

最關鍵就是將題目條件轉化,機器人工作時間T只與走過的區間長度L有關(T=2^(L-1)),因此題目轉化為:求出一個最短區間,滿足如下限制:

  • 區間的並集∪必須包含[1,n]所有的方格,即必須要能清掃所有方格
  • 每個區間內必須至少包含一個機器人,機器人在某個區間的任意位置工作時間都是一樣的,無需限定機器人一定要在區間的中點

方法一:二分查詢區間

可以從分析思路中得知區間1<=L<=n,因此用二分找到此區間長度L

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * 
 */
public class Main {
    //下標均從1開始
    static int N=100000+5;
	static int[] robotIdx=new int[N];
	static int n;
	static int k;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] line = reader.readLine().split(" ");
        n=Integer.parseInt(line[0]);
        k=Integer.parseInt(line[1]);
        for (int i = 0; i < k; i++) {
            line=reader.readLine().split(" ");
            robotIdx[i+1]=Integer.parseInt(line[0]);
        }
        //左閉右開,對機器人座標排序,因為後面需要遍歷機器人
        Arrays.sort(robotIdx,1,k+1);
        //找到能全覆蓋的最小區間
        int l=1,r=n;
        while (l<r) {
            int mid=(l+r)>>1;
            if (check(mid)) {
                r=mid;
            }else{
                l=mid+1;
            }
        }
        System.out.println(2*(l-1));
    }
    //此區間長度能掃完則返回true,否則返回false
    private static boolean check(int length) {
        int hasClear=0;
        for (int i = 1; i <= k ; i++) {
            //這個掃地機器人必須能接上上一個掃過的位置
            if (robotIdx[i]-length<=hasClear) {
                if (robotIdx[i]<=hasClear) {
                    hasClear=robotIdx[i]+length-1;
                }else{
                    hasClear+=length;
                }
            }else{
                //接不上
                return false;
            }
        }
        return hasClear>=n;
    }
}

方法二:dfs查詢區間

當區間長度為6時可能出現如下情況:

因此區間分佈由兩個變數決定,區間長度和第一個區間的顯現的長度,從這兩個出發dfs所有情況,時間複雜度約為:區間長度種類×第一個區間長度變化≈N²=1e10,可能會爆。

程式碼待補充。