原题链接:传送门
思路:首先就是理解题意,这道题我看了一天了,现在还是没整出来,错误50%,可能是中间产生溢出了。
这是一道组合题,重点就是最高位的选取,我们分成两种情况来考虑
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll C(int n,int m)
{
ll ans=1;
if(m<n-m)
m=n-m;
for(int i=m+1;i<=n;i++)
ans*=i;
for(int i=1;i<=n-m;i++)
ans/=i;
return ans;
}
int main()
{
int k,w,max;
ll ans=0;
scanf("%d%d",&k,&w);
for(int i=2;i<=w/k;i++)
ans+=C(pow(2,k)-1,i);
max=pow(2,w%k)-1;
for(int i=1;i<=max;i++)
ans+=C(pow(2,k)-1-i,w/k);
printf("%lld\n",ans);
return 0;
}
错误50%,待更
借鉴思路:传送门
更新:就是没有注意写的组合数函数还必须满足的一个条件(m<=n)
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll C(int n,int m)
{
if(m>n)return 0;//这是最重要的,没有这个错误50%
else
{
ll ans=1;
if(m<n-m)
m=n-m;
for(int i=m+1;i<=n;i++)
ans*=i;
for(int i=1;i<=n-m;i++)
ans/=i;
return ans;
}
}
int main()
{
int k,w,max;//max在第二种情况下高位取的最大值
ll ans=0;
scanf("%d%d",&k,&w);
for(int i=2;i<=w/k;i++)//w/k是分成的段
ans+=C(pow(2,k)-1,i);
max=pow(2,w%k)-1;
for(int i=1;i<=max;i++)
ans+=C(pow(2,k)-1-i,w/k);
printf("%lld\n",ans);
return 0;
}
总结:这道题在C语言网能够AC,在洛谷只拿了50分。原因:传送门(这是自己在C语言网写的题解)。
待更(洛谷AC后回来补题)