日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人

發布時間:2024/5/17 c/c++ 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019年第十屆藍橋杯 - 省賽 - C/C++研究生組 - G. 掃地機器人


Ideas

首先我們根據數學常識可以知道,當每個機器人清掃的范圍差不多時,最好都是 N / K,花的時間應該是最少的。

所以這道題實際上就是讓我們搜索每個機器人負責清掃的范圍,我們假設這個范圍是x。

既然是搜索,那么首先想到的就是二分,不斷的縮小x的過程中確保所有機器人的清掃范圍能夠覆蓋N個方格。

二分不是很麻煩,所以重點是確保所有機器人的清掃范圍能夠覆蓋N個方格。

給定一個x之后,我們可以遍歷每個機器人所在的位置依次判斷,因為題目中給出的機器人的位置并不是有序的,所以讀入數據之后還要先排序。

我們可以設置一個 total 變量,表示從左到右依次能夠清掃的范圍。

對于每一個機器人所在的位置k[i],如果k[i] - x,也就是機器人能夠清掃的左邊界小于total的話,分成兩種情況:

  • k[i] < total: 說明前面一個機器人k[i - 1]能夠清掃的右邊界達到k[i]的起始位置,那么第i個機器人就不用往左邊走了,此時前i個機器人能夠清掃的total = k[i] + x - 1;
  • k[i] >= total: 說明前面一個機器人k[i - 1]能夠清掃的右邊界沒有達到k[i]的起始位置,那么第i個機器人就需要往左邊清掃,而此時前i個機器人能夠清掃的total = total + x;
  • 如果 k[i] - x > total 的話,也就是第 i 個機器人能夠清掃的左邊界都大于前 i - 1 個機器人能夠清掃到的范圍,那說明這個 x 選的太小了,得增大范圍。

    最后找到了合適的 x 之后,那么花費時間最長的機器人,就是這個機器人的位置正好在 x 的中間,它需要先往左掃,再回來,然后往右掃,再回來,所以花費的最長時間為 (x - 1) * 2。

    然后我們就可以開始寫代碼啦。

    Code

    C++

    #include <iostream> #include <algorithm>using namespace std;const int maxn = 1e5+7; int n, m; int robot_list[maxn];bool check(int x) {int total = 0;for (int i = 0; i < m; i++) {if (robot_list[i] - x < total + 1) {if (robot_list[i] < total + 1) {total = robot_list[i] + x - 1;} else {total += x;}} else {return false;}}return total > n - 1; }int main() {cin >> n >> m;for (int i = 0; i < m; i++) {cin >> robot_list[i];}sort(robot_list, robot_list + m); int left = 0, right = n, middle, ans;while (left < right + 1) {middle = (right + left) >> 1;if (check(middle)) {right = middle - 1;ans = middle;} else {left = middle + 1;}}cout << (ans - 1) * 2 << endl;return 0; }

    Python

    def check(x):total = 0 # 前面的機器人能夠清掃的右邊界,初始化為0for i, v in enumerate(robot_list):if v - x < total + 1:if v < total + 1:total = v + x - 1else:total += xelse:return Falsereturn total > n - 1if __name__ == '__main__':# 1. 處理輸入數據n, k = map(int, input().split())robot_list = []for _ in range(k):robot_list.append(int(input()))robot_list.sort()# 2. 二分查找left, right, ans = 0, n, nwhile left < right + 1:middle = (right + left) >> 1if check(middle): # 如果此時確定的清掃范圍可以滿足條件則繼續縮小范圍ans = middleright = middle - 1else:left = middle + 1print((ans - 1) * 2)

    在線評測:https://www.acwing.com/problem/content/3179/

    總結

    以上是生活随笔為你收集整理的2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。