首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

HDU 4768:Flyer(傳單分發——二分查找)

     編輯:C++ 入門

問題大意:有 n 種傳單,第 i 種從位置 a_i 開始,每隔 c_i 分發一份,直到 b_i 為止。收到奇數份傳單的同學視為「不幸運」。樣例保證至多一名不幸運同學。若無則輸出 "DC Qiang is unhappy!",否則輸出該同學位置與收到份數。

解題思路:二分答案

關鍵性質:若區間 [l, r] 內有且只有一人收到奇數份,則該區間總份數為奇數。利用此性質二分定位不幸運同學位置。

  1. 先判斷整個範圍 [L, R] 總份數奇偶。若為偶,直接輸出 unhappy。
  2. 二分查找:設 mid = (l+r)/2,若 [mid, R] 總份數為奇,則不幸運同學在右半段(l = mid+1),否則在左半段(r = mid)。
  3. 統計區間份數時需注意起始位置對齊,非單純長度除以間距。

核心代碼

ll judge(ll k) { // 計算 [k, R] 區間總份數
    ll c = 0;
    for (int i = 0; i < n; i++) {
        ll x = min(R, d[i].b) - d[i].a;
        ll y = min(k, d[i].b) - d[i].a;
        if (x >= 0) c += (x / d[i].c + 1);
        if (y >= 0) c -= (y / d[i].c + 1);
    }
    return c;
}

ll solve() {
    while (l < r) {
        ll mid = (l + r) / 2;
        if (judge(mid) & 1) l = mid + 1;
        else r = mid;
    }
    return l;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved