UPC Go Home(貪心 || 前綴和+二分)(STL二分函數的使用)

Go Home

題目描述
There is a kangaroo at coordinate 0 on an infinite number line that runs from left to right, at time 0. During the period between time i−1 and time i, the kangaroo can either stay at his position, or perform a jump of length exactly i to the left or to the right. That is, if his coordinate at time i−1 is x, he can be at coordinate x−i, x or x+i at time i. The kangaroo’s nest is at coordinate X, and he wants to travel to coordinate X as fast as possible. Find the earliest possible time to reach coordinate X.

Constraints
X is an integer.
1≤X≤109

輸入
The input is given from Standard Input in the following format:
X
輸出
Print the earliest possible time for the kangaroo to reach coordinate X.
樣例輸入 Copy
6
樣例輸出 Copy
3
提示
The kangaroo can reach his nest at time 3 by jumping to the right three times, which is the earliest possible time.

題意: 從原點出發,在時間i可以走i的路程,可以向左向右或不動。問到達x的最短時間。
思路:
(1)貪心:一直往右走是時間最短的。會有兩種情況:在i時恰好到達x,或在i時超過x;對於前者一定是最短時間,對於後者我們可以在時間i之前選擇往左走,從而使i時恰好到達x;這也就引出了方法二
(2)前綴和+二分:基於(1)的分析我們可以維護一個前綴和數組。找數組中第一個>=x的位置即可。
代碼:
(1)貪心(模擬)

#include<bits/stdc++.h>
using namespace std;
int x,start;
void solve(){
    cin>>x;
    for(int i=1;i<=x;i++){
        start+=i;
        if(start>=x){
            cout<<i<<endl;
            break;
        }
    }
}
int main(){
    solve();
    return 0;
}

(2)前綴和+二分(手寫二分)

#include<bits/stdc++.h>
using namespace std;
const int maxn=50000;
int a[maxn],x;
void solve(){
    for(int i=1;i<maxn;i++) a[i]=a[i-1]+i;
    cin>>x;
    int l=0,r=maxn-1,res=0;
    while(l<=r){
        int mid=l+(r-l)/2;
        if(a[mid]>=x) r=mid-1;
        else if(a[mid]<x)l=mid+1;
    }
    cout<<l<<endl;
}
int cutele(){
    solve();
    return 0;
}

(3)STL 二分

#include<bits/stdc++.h>
using namespace std;
const int maxn=50000;
int a[maxn],x;
void solve(){
    for(int i=1;i<maxn;i++) a[i]=a[i-1]+i;
    cin>>x;
    int ans=lower_bound(a,a+maxn,x)-a;
    cout<<ans<<endl;
}
int cutele(){
    solve();
    return 0;
}

知識補充:
1.如果用mid=(left+right)/2,如果right是int上限一半還多,那麼可能導致溢出,使用mid=left+(right-left)/2可以代替以避免溢出
2.lower_bound(first,last,val)函數在[first,last)進行二分查找返回大於或等於val的第一個元素的位置,如果是數組,返回該位置指針,若沒有則返回last的位置。upper_bound()與lower_bound()相似,查找的是第一個大於val的元素的位置。舉個栗子0v0:數組a={1,2,4,4,4,5,7,9,9,10,13,17},想查找4第一次出現位置,lower_bound(a,a+n,4)-a,返回值是2.

參考資料: 二分總結_
算法複習——二分(二分查找,stl lower_bound()、upper_bound()木棒切割,快速冪)

保持熱愛,奔赴山海。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章