T1 确实不难,但 dalao 们都用的记忆化搜索。正如大部分人所言,朴素的搜索会 T 掉两个点。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,k,ans;
#define mid ((l+r)>>1)
void solve(ll l,ll r)
{
if(r-l-1>2*k)
{
ans++;
solve(l,mid);
solve(mid,r);
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin>>n>>k;
solve(1,n+1);
cout<<ans+1<<endl;
return 0;
}
但是比赛时口胡一下伪正解并特判 k=1,竟然 A 了。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,k,ans;
void solve(const ll l,const ll r)
{
const ll mid=(l+r)>>1;
if(r-l-1>2*k)
{
ans++;
if(mid-l-1>2*k) ans<<=1;
solve(mid,r);
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin>>n>>k;
if(k==0)
{
cout<<n<<endl;
return 0;
}
solve(1,n+1);
cout<<ans+1<<endl;
return 0;
}
最奇怪的是,本代码并没有通过样例 #4,却可以 AC,可见数据强度之弱。建议多组询问。出题人有必要重造数据(?)。
问题在于分析上述两个程序的时间复杂度和正确性。
显然,第一种时间复杂度是 O(n),正确性应该是无疑的。但对于第二个就有疑问,求解答。/kel