題目解析
這道題目是一道模擬加調和級數,難的就是調和級數,模擬過程比較簡單。
做法
這道題目的難點在于我們在玩這個跳的過程,可能出現來回跳的情況,那么為了解決這種情況,我們采取的方法是設定其的上限步數。那么怎么確定其的上限步數呢?(剛開始我也沒想到怎么去確定,聽了y總的講解后大悟還可以這樣玩。)我們可以想情況要么它就是中間都是1步,從最左邊到最右邊,然后又從最右邊到最左邊(極限情況),如果這時候再從最左邊往右肯定就是超了,那么其的步數就是2*N/1。但是它中間也有可能是2步或者3步,這里我們也要去取極限。那么最終的最大的步數就是2N/1+2N/2+…+2N/N。那么其實有很多人不理解為什么要這樣折騰,只弄一次的不就好了嗎,這里我給大家畫個圖大家就能明白了。
那么其實我們是在對每一種情況去取極限,防止它超。
那么我們來計算一下最大步數。
這里面設計到調和級數的計算,大家可以看一下數學
那么我們這里的估計是24N,我們可以再往上取一點,因為我們這里忽略了0.577,那么就是26N左右。
#include<iostream>
using namespace std;
const int N=1e6;
int q[N],b[N];//q記錄是炮彈還是板,b記錄炮彈和反板的數值
bool st[N];//記錄每個狀態
int main()
{int n,x;cin>>n>>x;for(int i=1;i<=n;i++)cin>>q[i]>>b[i];//int cnt=0,ans=0,d=1,m=1;//cnt記錄步數,d是方向,m是能量`while(cnt<26*n){if(q[x])//如果是炮彈{if(!st[x]&&m>=b[x]){st[x]=true;//標記一下,這里的炮彈被擊破ans++;}}else{d=-d;//改變方向m+=b[x];//能量改變}x+=m*d;//移動if(x<=0||x>n)break;cnt++;}cout<<ans;return 0;
}