SRM454 div1 medium

メモ化再帰
数字の処理がややこしい+コピペミスで150点。

#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;

class NumbersAndMatches
{
	public:
		int len;
		int number[20];
		int addMatch[10][10];
		int moveMatch[10][10];
		LL cache[20][300][200];

		LL rec(int k,int leftMatch,int canMove)
		{
			LL &r=cache[k][leftMatch][canMove];
			if(r!=-1)
				;
			else if(k==len)
				return r=(leftMatch==0)?1:0;
			else
			{
				r=0;
				int now=number[k];
				for(int i=0;i<10;i++)
					if(moveMatch[now][i]<=canMove)
						r+=rec(k+1,leftMatch+addMatch[now][i],canMove-moveMatch[now][i]);
			}
			return r;
		}

		LL differentNumbers(LL N, int canMove)
		{
			char numTable[3][100]={" _     _  _     _  _  _  _  _ ",
			                       "| |  | _| _||_||_ |_   ||_||_|",
			                       "|_| _||_  _|  | _||_|  ||_| _|"};

			for(int i=0;i<10;i++)
				for(int j=0;j<10;j++)
				{
					addMatch[i][j]=0;
					moveMatch[i][j]=0;
					for(int y=0;y<3;y++)
						for(int x=0;x<3;x++)
						{
							if(numTable[y][x+i*3]!=' ')
								addMatch[i][j]++;
							if(numTable[y][x+j*3]!=' ')	
								addMatch[i][j]--;
							if(numTable[y][x+i*3]!=' ' && numTable[y][x+j*3]==' ')
								moveMatch[i][j]++;
						}
				}
			len=0;
			for(int i=0;N!=0;i++)
			{
				len++;
				number[i]=N%10;
				N/=10;
			}
			memset(cache,-1,sizeof(cache));

			return rec(0,0,canMove);
		}
};