大数问题,地址: http://acm.pku.edu.cn/JudgeOnline/problem?id=1306
/** */
/***********************************************************************************************
无符号大整数类,包括了*和+法,类可以用小整数或者字符串输入,储存方式为:下标大的位储存高位
字符串输入时,必须手动去除前面多余的0
加法函数和乘法函数中,前2个参数为输入,最后个返回,参数中,前两个可以相同,但是最后个不能和前面的重复
减法函数中,被减数a必须大于减数b,返回到a中,要算c=a-b可以用Cpy,Sub两个函数合用
***********************************************************************************************/
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
const int OneNode = 1000000 ; /**/ /*一位里不能超过OneNode*/
const int NodeLen = 6 ; /**/ /*一位储存NodeLen位,和OneNode必须同时更改,输出部分格式必须跟随这里!!!*/
const int NumMax = 1005 ; /**/ /*储存位数限制,真实位数为NumMax*6*/
struct BigNum
{
unsigned num[NumMax] ;/**//*高位 对 下标大位*/
unsigned numlen ;
void set(unsigned sm=0){ num[0] = sm ; numlen = 1; }/**//*sm<OneNode*/
void set(char *string , int strlen)
{
numlen = (strlen-1) / NodeLen + 1 ;
memset (num , 0 , sizeof(unsigned)*numlen );
int temp , i ;
for( i=strlen-1 ; i>=0 ; i-- )
{
temp = i / NodeLen ;
num[temp] = num[temp]*10 + string[strlen-1-i]-'0' ;
}
}
void print()
{
printf("%d",num[numlen-1]);
int i = numlen-1;
while( i )
{
i--;
printf("%06d",num[i]);
}
printf(" ");
}
} ;
void Add(BigNum & a,BigNum & b,BigNum & c) /**/ /*a+b ->c*/
{
unsigned lenmax = a.numlen>b.numlen?a.numlen:b.numlen;
c.numlen = lenmax;
unsigned i,carry=0;
for ( i=0 ; i<lenmax ; i++ )
{
c.num[i] = carry ;
if( a.numlen > i )
c.num[i]+= a.num[i];
if( b.numlen > i )
c.num[i]+= b.num[i];
carry = c.num[i] / OneNode ;
c.num[i] %= OneNode ;
}
if ( carry )
{
c.num[i] = carry ;
c.numlen ++;
}
}
void Cpy(BigNum & a , BigNum & b) /**/ /*b-->a*/
{
a.numlen=b.numlen;
memcpy(a.num,b.num,sizeof(unsigned)*b.numlen);
}
BigNum number[ 105 ];
BigNum temp;
int main()
{
int i,j,n,m,c;
while(1)
{
scanf("%d%d",&n,&m);
if(n==0&&m==0)break;
c=m;
if(n-m<m)m=n-m;
number[0].set("1",1);
for(i=1;i<=n;i++)
{
if(i<=m)
{
number[i].set("1",1);
for(j=i-1;j>=1;j--)
{
Add(number[j],number[j-1],temp);
Cpy(number[j],temp);
}
}
else
{
for(j=m;j>=1;j--)
{
Add(number[j],number[j-1],temp);
Cpy(number[j],temp);
}
}
}
printf("%d things taken %d at a time is ",n,c);
number[m].print();
printf("exactly.\n");
}
return 0;
}
无符号大整数类,包括了*和+法,类可以用小整数或者字符串输入,储存方式为:下标大的位储存高位
字符串输入时,必须手动去除前面多余的0
加法函数和乘法函数中,前2个参数为输入,最后个返回,参数中,前两个可以相同,但是最后个不能和前面的重复
减法函数中,被减数a必须大于减数b,返回到a中,要算c=a-b可以用Cpy,Sub两个函数合用
***********************************************************************************************/
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
const int OneNode = 1000000 ; /**/ /*一位里不能超过OneNode*/
const int NodeLen = 6 ; /**/ /*一位储存NodeLen位,和OneNode必须同时更改,输出部分格式必须跟随这里!!!*/
const int NumMax = 1005 ; /**/ /*储存位数限制,真实位数为NumMax*6*/
struct BigNum
{
unsigned num[NumMax] ;/**//*高位 对 下标大位*/
unsigned numlen ;
void set(unsigned sm=0){ num[0] = sm ; numlen = 1; }/**//*sm<OneNode*/
void set(char *string , int strlen)
{
numlen = (strlen-1) / NodeLen + 1 ;
memset (num , 0 , sizeof(unsigned)*numlen );
int temp , i ;
for( i=strlen-1 ; i>=0 ; i-- )
{
temp = i / NodeLen ;
num[temp] = num[temp]*10 + string[strlen-1-i]-'0' ;
}
}
void print()
{
printf("%d",num[numlen-1]);
int i = numlen-1;
while( i )
{
i--;
printf("%06d",num[i]);
}
printf(" ");
}
} ;
void Add(BigNum & a,BigNum & b,BigNum & c) /**/ /*a+b ->c*/
{
unsigned lenmax = a.numlen>b.numlen?a.numlen:b.numlen;
c.numlen = lenmax;
unsigned i,carry=0;
for ( i=0 ; i<lenmax ; i++ )
{
c.num[i] = carry ;
if( a.numlen > i )
c.num[i]+= a.num[i];
if( b.numlen > i )
c.num[i]+= b.num[i];
carry = c.num[i] / OneNode ;
c.num[i] %= OneNode ;
}
if ( carry )
{
c.num[i] = carry ;
c.numlen ++;
}
}
void Cpy(BigNum & a , BigNum & b) /**/ /*b-->a*/
{
a.numlen=b.numlen;
memcpy(a.num,b.num,sizeof(unsigned)*b.numlen);
}
BigNum number[ 105 ];
BigNum temp;
int main()
{
int i,j,n,m,c;
while(1)
{
scanf("%d%d",&n,&m);
if(n==0&&m==0)break;
c=m;
if(n-m<m)m=n-m;
number[0].set("1",1);
for(i=1;i<=n;i++)
{
if(i<=m)
{
number[i].set("1",1);
for(j=i-1;j>=1;j--)
{
Add(number[j],number[j-1],temp);
Cpy(number[j],temp);
}
}
else
{
for(j=m;j>=1;j--)
{
Add(number[j],number[j-1],temp);
Cpy(number[j],temp);
}
}
}
printf("%d things taken %d at a time is ",n,c);
number[m].print();
printf("exactly.\n");
}
return 0;
}