【普及/提高?】洛谷P1577 ——切繩子

見:P1577 切繩子 - 洛谷

題目描述

有?N?條繩子,它們的長度分別為?Li?。如果從它們中切割出?K?條長度相同的繩子,這?K?條繩子每條最長能有多長?答案保留到小數點后?2?位(直接舍掉?2?位后的小數)。

輸入格式

第一行兩個整數?N?和?K,接下來?N?行,描述了每條繩子的長度?Li??。

輸出格式

切割后每條繩子的最大長度。答案與標準答案誤差不超過?0.01?或者相對誤差不超過?1%?即可通過。

輸入輸出樣例

in:
4 11
8.02
7.43
4.57
5.39
out:
2.00

說明/提示

對于?100%?的數據?0<Li?≤100000.00,0<n≤10000,0<k≤10000

第一步

code

#include<bits/stdc++.h>
using namespace std;
const int q=1e4+5;
int n,k;
double z[q];bool ch(double x){int ans=0;for(int i=0;i<n;i++){ans+=floor(z[i]/x);if(ans>=k) return true;}return false;
}int main(){cin>>n>>k;for(int i=0;i<n;i++) cin>>z[i];double l=0,r=1e9;while(r-l>=1e-4){double mid=l+(r-l)/2;if(ch(mid)) l=mid;else r=mid;}printf("%.2f",floor(l*100)/100);return 0;
}

第二步

分析

問題背景與應用場景

這個問題在現實生活中有很多應用場景,比如:

  • 電纜切割:將不同長度的電纜切割成若干等長的小段,以滿足至少k段的需求,同時最大化每段的長度。
  • 土地劃分:將不同面積的土地劃分為至少k塊相等面積的小地塊,求最大可能的地塊面積。
  • 布料裁剪:將不同長度的布料裁剪成至少k條等長的布條,以最大化每條布條的長度。

代碼詳細分析

全局變量與常量定義
const int q=1e4+5;
int n,k;
double z[q];
  • q是一個常量,表示數組的最大長度,這里設置為 10005,足夠處理題目中可能出現的最大數據量。
  • nk是兩個整數變量,分別表示材料的數量和需要切割出的段數。
  • z[q]是一個雙精度浮點數數組,用于存儲每個材料的長度。
核心判斷函數ch(double x)
bool ch(double x){int ans=0;for(int i=0;i<n;i++){ans+=floor(z[i]/x);if(ans>=k) return true;}return false;
}

這個函數的作用是判斷是否可以將所有材料切割成至少k段,每段長度為x。具體邏輯如下:

  1. 初始化計數器ans為 0。
  2. 遍歷每個材料,計算該材料可以切割出多少段長度為x的小段,使用floor(z[i]/x)確保結果為整數。
  3. 累加每段材料可切割的段數到ans中。
  4. 如果在遍歷過程中發現ans已經達到或超過k,則立即返回true,表示可以切割出足夠的段數。
  5. 如果遍歷完所有材料后ans仍小于k,則返回false
主函數main()
int main(){cin>>n>>k;for(int i=0;i<n;i++) cin>>z[i];double l=0,r=1e9;while(r-l>=1e-4){double mid=l+(r-l)/2;if(ch(mid)) l=mid;else r=mid;}printf("%.2f",floor(l*100)/100);return 0;
}

主函數實現了二分查找算法,用于找到最大的可行切割長度,具體步驟如下:

  1. 讀取輸入數據:首先讀取材料數量n和需要切割的段數k,然后讀取每個材料的長度并存儲在數組z中。
  2. 初始化二分查找的左右邊界:左邊界l初始化為 0,右邊界r初始化為一個足夠大的值(1e9),確保包含所有可能的答案。
  3. 執行二分查找:在r-l >= 1e-4的條件下循環,這個條件控制了二分查找的精度,當左右邊界的差距小于 1e-4 時停止循環。
  4. 計算中間值mid:使用l + (r - l) / 2計算中間值,避免直接使用(l + r) / 2可能導致的溢出問題。
  5. 判斷中間值是否可行:調用ch(mid)函數,如果返回true,說明中間值mid是一個可行解,更新左邊界l = mid;否則更新右邊界r = mid
  6. 輸出結果:循環結束后,l的值即為所求的最大可行切割長度,但需要保留兩位小數。使用floor(l*100)/100確保結果精確到小數點后兩位,然后使用printf("%.2f", ...)輸出結果。

算法思路與二分查找的應用

這個問題的核心思路是利用二分查找來高效地找到最優解。二分查找適用于這種最大化最小值或最小化最大值的問題,其關鍵在于能夠快速判斷一個給定的值是否可行。

具體來說,二分查找的應用場景需要滿足以下條件:

  1. 解空間具有單調性:在這個問題中,如果長度x是可行的,那么所有小于x的長度也都是可行的;反之,如果長度x不可行,那么所有大于x的長度也都不可行。
  2. 存在明確的判斷條件:通過ch函數可以快速判斷一個給定的長度是否可行。

二分查找的時間復雜度是 O (log (max_length)),其中 max_length 是右邊界的值。在每次迭代中,需要遍歷所有材料一次,時間復雜度為 O (n),因此總的時間復雜度為 O (n log (max_length)),這使得算法在處理大規模數據時仍然高效。

精度控制與輸出處理

在處理浮點數二分查找時,精度控制是一個關鍵問題。代碼中使用r - l >= 1e-4作為循環條件,確保結果的精度在小數點后四位。這是因為在實際應用中,我們通常只需要保留兩位小數的結果,而額外的精度可以避免由于浮點數計算誤差導致的結果偏差。

輸出處理部分使用了floor(l*100)/100來確保結果精確到小數點后兩位。這是因為直接使用%.2f格式化輸出可能會進行四舍五入,而題目要求是直接截斷到兩位小數。例如,如果計算結果是 3.149,floor(3.149*100)/100會得到 3.14,而不是 3.15。

代碼優化與擴展

輸入驗證

當前代碼沒有對輸入進行驗證,在實際應用中可以添加輸入驗證以增強代碼的健壯性。例如:

if (k <= 0) {cout << "Error: k must be a positive integer." << endl;return 1;
}
右邊界優化

初始右邊界設置為 1e9 可能過大,可以根據輸入數據動態設置右邊界,例如:

double max_z = 0;
for(int i=0;i<n;i++) {cin>>z[i];max_z = max(max_z, z[i]);
}
double l=0, r=max_z;

這樣可以減少二分查找的迭代次數,提高效率。

處理無解情況

如果所有材料的總長度小于k,則無論如何都無法切割出k段,此時應輸出 0。可以在開始時添加檢查:

double sum = 0;
for(int i=0;i<n;i++) {sum += z[i];
}
if (sum < k) {cout << "0.00" << endl;return 0;
}
代碼可讀性優化

可以添加注釋來提高代碼的可讀性,例如:

// 檢查是否可以將所有材料切割成至少k段,每段長度為x
bool ch(double x){// ... 函數體 ...
}// 主函數:二分查找最大可行切割長度
int main(){// ... 主函數體 ...
}

復雜度分析

  • 時間復雜度:O (n log (max_length)),其中 n 是材料的數量,max_length 是右邊界的值。
  • 空間復雜度:O (n),主要用于存儲材料長度的數組。

測試用例

以下是一些測試用例,可以幫助驗證代碼的正確性:

  1. 基本測試

    • 輸入:n=3, k=4,?z=[10, 20, 30]
    • 輸出:15.00
    • 解釋:每段長度為 15 時,可切割出0+1+2=3段,不足 4 段;每段長度為 14 時,可切割出0+1+2=3段,不足 4 段;每段長度為 13 時,可切割出0+1+2=3段,不足 4 段;每段長度為 12 時,可切割出0+1+2=3段,不足 4 段;每段長度為 11 時,可切割出0+1+2=3段,不足 4 段;每段長度為 10 時,可切割出1+2+3=6段,滿足條件,且為最大可行長度。
  2. 邊界測試

    • 輸入:n=1, k=1,?z=[5.0]
    • 輸出:5.00
    • 解釋:只有一段材料,長度為 5,切割成 1 段,最大長度為 5。
  3. 精度測試

    • 輸入:n=2, k=3,?z=[1.0, 2.0]
    • 輸出:0.66
    • 解釋:每段長度為 0.66 時,可切割出1+3=4段,滿足條件;每段長度為 0.67 時,可切割出1+2=3段,滿足條件,但 0.67 不是最大可行長度,最大可行長度為 0.666...,截斷后為 0.66。

總結

這段代碼通過二分查找高效地解決了材料切割的最大化最小值問題,關鍵在于合理設計判斷函數ch和精確控制二分查找的邊界與精度。代碼結構清晰,算法效率高,適用于處理大規模數據。在實際應用中,可以根據具體需求進行進一步優化和擴展,如添加輸入驗證、處理無解情況等,以提高代碼的健壯性和實用性。


完結撒花hi?(。???。)??

對了

聽說給點贊+關注+收藏的人會發大財哦(o゚▽゚)o ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88451.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88451.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88451.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

imx6ull-裸機學習實驗16——I2C 實驗

目錄 前言 I2C簡介 基本特性?? I2C 協議 起始位 停止位 數據傳輸 應答信號 I2C 寫時序 I2C 讀時序 I.MX6U I2C 簡介 寄存器 地址寄存器I2Cx_IADR(x1~4) 分頻寄存器I2Cx_IFDR 控制寄存器I2Cx_I2CR 狀態寄存器I2Cx_I2SR 數據寄存器I2Cx_I2DR AP3216C 簡介 …

【TCP/IP】5. IP 協議

5. IP 協議5. IP 協議5.1 概述5.2 IP 數據報格式5.3 無連接數據報傳輸5.3.1 首部校驗5.3.2 數據分片與重組5.4 IP 數據報選項5.4.1 選項格式5.4.2 選項類型5.5 IP 模塊的結構本章要點5. IP 協議 5.1 概述 IP 協議是 TCP/IP 協議簇的核心協議&#xff0c;位于網絡層&#xff0…

Linux 服務器挖礦病毒深度處理與防護指南

在 Linux 服務器運維中&#xff0c;挖礦病毒是常見且危害較大的安全威脅。此類病毒通常會隱蔽占用大量 CPU 資源進行加密貨幣挖礦&#xff0c;導致服務器性能驟降、能耗激增&#xff0c;甚至被黑客遠程控制。本文將從病毒特征識別、應急處理流程、深度防護措施三個維度&#xf…

MySQL數據表設計 系統的營銷功能 優惠券、客戶使用優惠券的設計

系統的營銷功能營銷功能概述&#xff1a;系統的營銷功能主要是&#xff1a;市場活動管理、營銷自動化、銷售線索管理以及數據分析和報告等。?ToC?&#xff08;Consumer&#xff09;&#xff1a;面向個人消費者&#xff0c;滿足日常消費需求。?優惠券的種類&#xff1a;ToC的…

讓 3 個線程串行的幾種方式

1、通過join()的方式 子線程調用join()的時候&#xff0c;主線程等待子線程執行完再執行。如果讓多個線程順序執行的話&#xff0c;那么需要他們按順序調用start()。/*** - 第一個迭代&#xff08;i0&#xff09;&#xff1a;* 啟動線程t1 -> 然后調用t1.join()。* …

在 Vue 項目中關閉 ESLint 規則

在 Vue 2 項目中關閉 ESLint 規則有以下幾種方法&#xff0c;根據您的需求選擇合適的方式&#xff1a; 1. 完全禁用 ESLint 修改 vue.config.js&#xff08;推薦&#xff09; module.exports {// 關閉 ESLintlintOnSave: false }或修改 package.json {"scripts": {&…

電腦息屏工具,一鍵黑屏超方便

軟件介紹 今天為大家推薦一款實用的PC端屏幕管理工具——CloseDsp。這款"息屏小能手"能一鍵關閉顯示器&#xff0c;解決各種場景下的屏幕管理需求。 核心功能 CloseDsp最突出的特點是能瞬間關閉顯示器屏幕。只需點擊"關閉顯示器"按鈕&#xff0c;屏幕…

嵌入式調試LOG日志輸出(以STM32為例)

引言在嵌入式系統開發中&#xff0c;調試是貫穿整個生命周期的關鍵環節。與傳統PC端程序不同&#xff0c;嵌入式設備資源受限&#xff08;如內存、存儲、處理器性能&#xff09;&#xff0c;且運行環境復雜&#xff08;無顯示器、鍵盤&#xff09;&#xff0c;傳統的斷點調試或…

Zephyr的設備驅動模型

默認配置默認配置 boards/arm/nucleo_f401re/ ├── nucleo_f401re.dts ← 板卡設備樹主入口 ├── nucleo_f401re_defconfig ← 默認 Kconfig 配置 ├── board.cmake ← CMake 構建入口overlay1.新增加驅動需要修改對應板的設備樹文件&#xf…

Mysql字段沒有索引,通過where x = 3 for update是使用什么級別的鎖

沒有索引時&#xff0c;FOR UPDATE 會鎖住整個表 現在&#xff0c;你正在一本一本地翻看所有書&#xff0c;尋找“維修中”的書&#xff0c;并且你對管理員說&#xff1a;“在我清點和修改完之前&#xff0c;別人不能動這些書&#xff0c;也不能往這個范圍里加新書&#xff01;…

TCP-與-UDP-協議詳解:原理、區別與應用場景全解析

TCP 與 UDP 協議詳解&#xff1a;原理、區別與應用場景全解析 在日常使用網絡的過程中&#xff0c;我們經常聽到 TCP 和 UDP 這兩個詞。你打開網頁、發送消息、觀看視頻&#xff0c;背后都在使用 TCP 或 UDP 進行數據傳輸。那么這兩個協議到底是怎么工作的&#xff1f;它們之間…

GitHub信息收集

目錄 簡介 一、入門搜索技巧 1. 基本關鍵詞搜索 2. 文件類型限定搜索 3. 用戶/組織定向搜索 二、精準定位技巧 1. 組合搜索條件 2. 排除干擾結果 3. 路徑限定搜索 三、防御建議 四、法律與道德提醒 簡介 GitHub作為全球最大的代碼托管平臺&#xff0c;存儲著數十億…

由 DB_FILES 參數導致的 dg 服務器無法同步問題

由 DB_FILES 參數導致的 dg 服務器無法同步問題 用戶反映&#xff0c;dg 服務器數據從昨晚&#xff08;7月8日&#xff09;開始停止同步。 連接服務器發現沒有 mrp 進程&#xff0c;并且 OPEN_MODE 參數也不正確。具體情況如下所示&#xff1a; SQL> select process, status…

Go語言泛型-泛型對代碼結構的優化

在Go語言中,Go泛型-泛型對代碼結構的優化部分主要探討了泛型如何幫助我們優化代碼結構、減少重復代碼,并提高代碼的可維護性、可讀性和復用性。以下是詳細內容: 一、引言 Go 1.18 引入了泛型,極大地提高了語言的靈活性。泛型使得我們可以編寫更加通用、可復用且類型安全的…

【1-快速上手】

文章目錄前言簡介什么是 Konva&#xff1f;安裝 Konva概述它是如何工作的&#xff1f;基本形狀樣式事件拖放濾鏡動畫選擇器序列化與反序列化性能前言 結合項目實際業務需求&#xff0c;在 Fabric、Konva 等圖形化框架中&#xff0c;我選擇了性能表現好的 Konva。首先去學習官方…

【LeetCode】209. 長度最小的子數組(前綴和 + 二分)

【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09;題目描述前綴和二分優化前綴和總結二分總結題目描述 題目鏈接&#xff1a;【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09; 給定一個含有 n 個整數的數組和一個整數 target。…

文件系統----底層架構

當我們談到文件系統的時候&#xff0c;最重要的點在于&#xff1a;文件的內容與屬性是如何存儲在磁盤中的&#xff1f;以及操作系統是如何精準定位到這些文件內容的&#xff1f;在談及文件的內核前&#xff0c;我們先來了解一下儲存文件的硬件-----硬盤一.理解硬件首先我們來看…

小程序開發平臺,自主開發小程序源碼系統,多端適配,帶完整的部署教程

溫馨提示&#xff1a;文末有資源獲取方式全開源與自主開發源碼完全開放&#xff1a;開發者可自由修改前端界面、后端邏輯及數據庫結構&#xff0c;支持深度定制&#xff08;如調整用戶端交互流程、商家端管理功能等&#xff09;。技術棧透明&#xff1a;基于主流技術&#xff0…

stp拓撲變化分類

Max Age 20sHellotime 2sForward delay 153、拓撲改變需要多長時間1&#xff09;根橋故障&#xff1a;需要50秒&#xff08;Max age2個forwarding delay&#xff09;2&#xff09;非直連鏈路&#xff1a;非直連故障在穩定的STP網絡&#xff0c;非根橋會定期收到來自根橋的BPDU報…

一、深度學習——神經網絡

一、神經網絡 1.神經網絡定義&#xff1a;人工神經網絡&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;也簡稱為神經網絡&#xff08;NN&#xff09;&#xff0c;是一種模仿生物神經網絡結構和功能的計算模型。人腦可以看作是一個生物神經網絡&#xff0c;由…