1. 程式人生 > 實用技巧 >7.18每日一題題解

7.18每日一題題解

樹上求和

涉及知識點:

  • 二分
  • 思維

solution:

  • 二分出答案
  • 假設答案是x的話,判斷我們至少刪除幾個可以到達x
  • 如果我們需要刪除的數量大於m的話,那麼此時答案一定是比小的(right = mid - 1)
  • 否則x就有可能是答案(left = mid)

std:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,l;
const int N = 5e4 + 10;
int a[N];

bool check(int x)
{
    int last = l;
    int cnt = 0;
    for(int i = n; i >= 0;i --)
    {
        if(last - a[i] < x){
            cnt ++; // 如果此時的距離比x小的話,那麼這個就可以被刪除
        }
        else{
            last = a[i]; // 更新最後一個石頭
        }
    }
    
    if(cnt > m)return false;
    else return true;
    
}

int main()
{
    cin >> l >> n >> m;
    
    for(int i = 1;i <= n;i ++)
    {
        cin >> a[i];
    }
    
    int left = 0,right = l;
    
    while(left < right)
    {
        int mid = left + right + 1 >> 1;
        if(check(mid)){
            left = mid;
        }
        else{
            right = mid - 1;
        }
    }
    
    cout << left << endl;
    
    return 0;
}