Monday 4 May 2009

POJ 1306


说是可以用double类型,但老用老错,烦了,直接上大数。
#include <iostream>
#include <deque>
#include <cmath>
#include <algorithm>
using namespace std;
typedef unsigned int uint;
typedef unsigned __int64 uint64;
class unsigned_big_integer{
protected:
typedef unsigned_big_integer class_type;
typedef uint celltype;
std::deque<celltype> m_num;
public:
unsigned_big_integer(const class_type& b):m_num(b.m_num){}
unsigned_big_integer(const uint integer):m_num(){
uint x=integer;
while(x){
m_num.push_front(x%10);
x/=10;
}
}
virtual ~unsigned_big_integer(){}
class_type& operator=(const class_type& bi){
this->m_num=bi.m_num;
return *this;
}
public:
virtual std::string str(){
std::string s(m_num.begin(),m_num.end());
for(std::string::iterator itr=s.begin();itr!=s.end();++itr)
*itr+='0';
return s;
}

class_type& mul(uint const x){
for(std::deque<celltype>::iterator itr=m_num.begin();itr!=m_num.end();++itr)
*itr*=x;
for(std::deque<celltype>::reverse_iterator ritr=m_num.rbegin();ritr!=m_num.rend()-1;++ritr){
*(ritr+1)+=(*ritr)/10;
*ritr%=10;
}
while(m_num.front()>=10){
celltype x=m_num.front()/10;
m_num.front()%=10;
m_num.push_front(x);
}
return *this;
}

class_type& operator/=(uint const x){
uint remained=0;
for(std::deque<celltype>::iterator itr=m_num.begin();itr!=m_num.end();++itr){
remained*=10;
remained+=*itr;
if(remained/x){
for(int j=9;j>=1;--j){
if(remained/(x*j)){
*itr=j;
remained-=x*j;
break;
}
}
}
else{
*itr=0;
}
}
for(;m_num.size()>1&&m_num.front()==0;m_num.pop_front())
;
return *this;
}

class_type& operator*=(uint const x){
return mul(x);
}
};

string C(uint n, uint m){
unsigned_big_integer x(n);
uint t=n-m;
for(--n;n>t;--n) x*=n;
for(;m>1;--m) x/=m;
return x.str();
}

int main() {
for(uint n,m;cin>>n>>m&&n&&m;)
cout<<n<<" things taken "<<m<<" at a time is "<<C(n,m)<<" exactly.\n";
return 0;
}

No comments:

Post a Comment