2的k次方进制数

题目链接

一个2k进制数

一个2k进制数从左到右每一位上的数分别表示20*k,21*k,22*k,……

转换为2进制后分别对应着0k-1,k2k-1,2k~3k

因为“r 的每一位严格小于它右边相邻的那一位”所以选出一些数来它们的排序方式是确定的,求组合数

#include<bits/stdc++.h>
using namespace std;
string f[600][600];
int aa[300],bb[300],cc[300];
string sum(string a,string b)
{
	memset(cc,0,sizeof(cc));
	memset(aa,0,sizeof(aa));
	memset(bb,0,sizeof(bb));
	int la=a.size(),lb=b.size(),lc=1,x=0;
	string c="\0";
	for(int i=0;i<la;i++) aa[la-i]=a[i]-'0';
	for(int i=0;i<lb;i++) bb[lb-i]=b[i]-'0';
	while(lc<=la||lc<=lb)
	{
		cc[lc]=aa[lc]+bb[lc]+x;
		x=0;
		if(cc[lc]>9) cc[lc]=cc[lc]%10,x=1;
		lc++;
	}
	lc--;
	if(x==1) cc[++lc]=1;
	for(int i=0;i<lc;i++) 
	{
		c+=(char)cc[lc-i]+'0';
	}
	return c;
}
int main()
{
	int k,w;
	string ans="0";
	cin>>k>>w;
	int k2=1<<k,n=w/k;
	f[0][0]="1";
	for(int i=1;i<=k2;i++)
		f[i][0]=f[i][i]="1";
	for(int i=1;i<k2;i++)
	for(int j=1;j<i;j++)
	f[i][j]=sum(f[i-1][j],f[i-1][j-1]);
	int minn=min(k2-1,n);
	for(int i=2;i<=minn;i++)
	ans=sum(ans,f[k2-1][i]);
	if(w%k)
	{
		int lim=(1<<(w%k))-1;
		for(int i=1;i<=lim;i++)
		{
			if(n>k2-1-i) 
			break;
			ans=sum(ans,f[k2-i-1][n]);
		}
	
	}
	cout<<ans;
	return 0;
 } 
posted @ 2020-09-16 11:23  zlq,  阅读(441)  评论(0编辑  收藏  举报