110603 Counting


#include <vector>
#include <iostream>

using namespace std;

class Integer
{
public:
	Integer(char* buf, int len)
	{
		for (int i = 0; i < len; ++i)
			m_data.push_back(buf[i] - '0');
	}

	Integer() {}

	void Print()
	{
		int cnt = m_data.size();

		if (cnt <= 0)
			cout << "0";

		for (int i = 0; i < cnt; ++i)
			cout << m_data[i];
	}

	void Add(const Integer& other)
	{
		Integer result;
		Add(other, result);
		m_data = result.m_data;
	}

	void Minus(const Integer& other)
	{
		Integer result;
		Minus(other, result);
		m_data = result.m_data;
	}

	void Multiply(const Integer& other)
	{
		Integer result;
		Multiply(other, result);
		m_data = result.m_data;
	}

	void Divide(const Integer& other)
	{
		Integer result;
		Divide(other, result);
		m_data = result.m_data;
	}

private:
	void Add(const Integer& other, Integer& result) const
	{
		result.m_data.clear();
		int flag = 0;
		int i = 0, limit = (other.m_data.size() > m_data.size()) ? other.m_data.size() : m_data.size();
		while(i < limit)
		{
			int num1 = (i < m_data.size()) ? m_data[m_data.size() - 1 - i] : 0;
			int num2 = (i < other.m_data.size()) ? other.m_data[other.m_data.size() - 1 - i] : 0;
			int sum = num1 + num2 + flag;
			flag = sum / 10;
			result.m_data.push_back(sum % 10);
			++i;
		}
		if (flag > 0)
			result.m_data.push_back(flag);

		result.ShrinkAndInvert();
	}

	void Minus(const Integer& other, Integer& result) const
	{
		result.m_data.clear();
		int flag = 0;
		int i = 0, limit = (other.m_data.size() > m_data.size()) ? other.m_data.size() : m_data.size();
		while(i < limit)
		{
			int num1 = (i < m_data.size()) ? m_data[m_data.size() - 1 - i] : 0;
			int num2 = (i < other.m_data.size()) ? other.m_data[other.m_data.size() - 1 - i] : 0;
			int left = num1 - flag - num2;
			if (left < 0)
			{
				flag = 1;
				left += 10;
			}
			else
				flag = 0;
			result.m_data.push_back(left);
			++i;
		}
		if (flag < 0)
			result.m_data.push_back(9);

		result.ShrinkAndInvert();
	}

	void Multiply(const Integer& other, Integer& result) const
	{
		result.m_data.clear();
		for (int i = other.m_data.size() - 1; i >= 0; --i)
		{
			Integer tmp, sum;
			Multiply(other.m_data[i], tmp, other.m_data.size() - i - 1);
			result.Add(tmp, sum);
			result = sum;
		}
	}

	void Multiply(const int n, Integer& result, int shift) const
	{
		result.m_data.clear();
		for (int i = 0; i < shift; ++i)
			result.m_data.push_back(0);

		int flag = 0;
		for (int i = m_data.size() - 1; i >= 0; --i)
		{
			int tmp = m_data[i] * n + flag;
			flag = tmp / 10;
			result.m_data.push_back(tmp % 10);
		}
		if (flag > 0)
			result.m_data.push_back(flag);

		result.ShrinkAndInvert();
	}

	void Divide(const Integer& other, Integer& result) const
	{
		result.m_data.clear();
		if (operator == (other))
		{
			result.m_data.push_back(1);
			return;
		}

		if (!(operator > (other)))
			return;

		int sizeDev = m_data.size() - other.m_data.size();
		Integer tmp = (*this);
		Integer resultTmp1, resultTmp2;
		for (int i = sizeDev; i >= 0; --i)
		{
			Integer tmp1, tmp2;
			other.Multiply(1, tmp1, i);
			int sum = 0;
			while(true)
			{
				if (tmp >= tmp1)
				{
					tmp.Minus(tmp1, tmp2);
					++sum;
					tmp = tmp2;
				}
				else
					break;
			}
			resultTmp1.m_data.clear();
			if (sum > 0)
			{
				for (int j = 0; j < i; ++j)
					resultTmp1.m_data.push_back(0);
				resultTmp1.m_data.push_back(sum);
				resultTmp1.ShrinkAndInvert();
			}
			result.Add(resultTmp1, resultTmp2);
			result = resultTmp2;
		}
	}

private:
	void ShrinkAndInvert()
	{
		while(m_data.size() != 0)
		{
			if (m_data[m_data.size() - 1] == 0)
				m_data.pop_back();
			else
				break;
		}

		int cnt = m_data.size();
		for (int i = 0; i < cnt / 2; ++i)
		{
			int tmp = m_data[i];
			m_data[i] = m_data[cnt - 1 - i];
			m_data[cnt - 1 - i] = tmp;
		}
	}

	bool operator > (const Integer& other) const
	{
		if (m_data.size() > other.m_data.size())
			return true;
		if (m_data.size() < other.m_data.size())
			return false;
		for (int i = 0; i < m_data.size(); ++i)
			if (m_data[i] < other.m_data[i])
				return false;
			else if (m_data[i] > other.m_data[i])
				return true;
		return false;
	}

	bool operator == (const Integer& other) const
	{
		if (m_data.size() != other.m_data.size())
			return false;
		for (int i = 0; i < m_data.size(); ++i)
			if (m_data[i] != other.m_data[i])
				return false;
		return true;
	}

	bool operator >= (const Integer& other) const
	{
		return ((operator > (other)) || (operator == (other)));
	}

private:
	vector<int> m_data;
};

static Integer* GetResult(int n, vector<Integer*>& results)
{
	if (results.size() > n)
		return results[n];

	Integer* finalResult = NULL;
	if (n < 1)
	{
		finalResult = new Integer("1", 1);
	}

	if (n >= 1)
	{
		finalResult = new Integer("0", 1);
		Integer* result_n_1 = GetResult(n-1, results);
		finalResult->Add(*result_n_1);
		finalResult->Add(*result_n_1);
	}

	if (n >= 2)
	{
		Integer* result_n_2 = GetResult(n-2, results);
		finalResult->Add(*result_n_2);
	}

	if (n >= 3)
	{
		Integer* result_n_3 = GetResult(n-3, results);
		finalResult->Add(*result_n_3);
	}

	results.push_back(finalResult);

	return finalResult;
}

static void DoTest(int n, vector<Integer*>& results)
{
	Integer* result = GetResult(n, results);
	result->Print();
}

static void Test()
{
	vector<Integer*> results;
	results.push_back(new Integer("1", 1));
	int n;
	while(cin >> n)
	{
		DoTest(n, results);
		cout << endl;
	}

	vector<Integer*>::iterator iter = results.begin();
	while (iter != results.end())
	{
		delete (*iter);
		++iter;
	}
}

int main(int argc, char* argv[])
{
	Test();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值