大數問題,地址: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;
}