#include <iostream>
#include <string>
#include <algorithm>
#include <map>

class NOS
{
public:
	NOS(const char* s="") : s(s) {}
	int value()const;
	const std::string& str()const { return s; }
	NOS& operator++();
	void expandAndReset();
	bool atMax()const;
	bool operator<(const NOS& rhs)const;
private:
	int zeroCount()const;
private:
	std::string s;
};

int main()
{
	int n = 500;
	std::map<int,NOS> results;
	NOS work = "0";
	while (results.size() != n || !work.atMax())
	{
		int val = work.value();
		if (val >= 1 && val <= n)
		{
			auto it = results.find(val);
			if (it == results.end() || work < it->second)
				results[val] = work;
		}
		if (work.atMax()) work.expandAndReset(); else ++work;
	}
	for (auto& p : results)
		std::cout << p.first << " => " << p.second.str() << "\n";
}


bool NOS::operator<(const NOS& rhs)const
{
	if (s.size() != rhs.s.size()) return s.size() < rhs.s.size();
	int zeroDiff = zeroCount() - rhs.zeroCount();
	return zeroDiff ? zeroDiff > 0 : s < rhs.s;
}

int NOS::zeroCount()const
{
	return std::count_if(s.begin(), s.end(), [](char c){ return c=='0'; });
}

bool  NOS::atMax()const
{
	return std::all_of(s.begin(), s.end(), [](char c){ return c=='2'; });
}
	
void NOS::expandAndReset()
{
	s = std::string(s.size()+1, '0');
}

NOS& NOS::operator++()
{
	int i = s.size() - 1;
	while (i >= 0) if (++s[i] > '2') s[i--] = '0'; else break;
	return *this;
}

int NOS::value()const
{
	int result = 0, operand = 1;
	for (char c : s)
		switch (c)
		{
		case '0': result += operand++; break;
		case '1': result -= operand++; break;
		case '2': result *= operand++; break;
		default: break;
		}
	return result;
}