比赛 AHOI09DAY2模拟 评测结果 AAAWTETWTW
题目名称 中国象棋 最终得分 30
用户昵称 Pom 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-09 12:07:03
显示代码纯文本
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int M=9999973;

int f[101][1<<8][1<<8],i,j,k,n,m,x,y,p1,p2,xx,yy,ans=0;

bool ok(int k1)
{
	int t=k1,re=0;
	while (t)
	{
		re+=t%2;
		t=t>>1;
	}
	if (re>2) return false;
	return true;
}

bool mat(int k1,int k2)
{
	int t1=k1,t2=k2;
	do
	{
		if (t2>t1) return false;
		if (t2%2 && !(t1%2)) return false;
		t2=t2>>1;
		t1=t1>>1;
	}
	while (t1 || t2);
	return true;
}

void get()
{
	p1=1;
	for (;;)
	{
		if ( (1<<p1-1) & j) break;
		++p1;
	}
	p2=p1+1;
	for (;;)
	{
		if ( (1<<p2-1) & j ) break;
		++p2;
		if (p2>m)
		{
			p2=0;
			break;
		}
	}
}

int main()
{
	freopen("cchess.in","r",stdin);
	freopen("cchess.out","w",stdout);
	scanf("%d%d",&n,&m);
	if (m>n) swap(m,n);
	for (i=0;i<1<<m;i++)
		if (ok(i)) f[1][i][0]=1;
	for (i=2;i<=n;i++)
	{
		for (j=0;j<1<<m;j++)
			if (ok(j))
				for (x=0;x<1<<m;x++)
					for (y=0;y<1<<m;y++)
						if (mat(x,y))
							if (!(x & j) || !(y & j))
							{
								if (j==0)
								{
									f[i][x][y]+=f[i-1][x][y];
									continue;
								}
								get();
								xx=x;
								yy=y;
								if (xx & (1<<p1-1)) yy=yy | (1<<p1-1);
								else xx=xx | (1<<p1-1);
								if (p2)
									if (xx & (1<<p2-1)) yy=yy | (1<<p2-1);
									else xx=xx | (1<<p2-1);
								f[i][xx][yy]+=f[i-1][x][y];
								f[i][xx][yy]=f[i][xx][yy]%M;
							}
	}
	for (i=0;i<1<<m;i++)
		for (j=0;j<1<<m;j++)
			ans+=f[n][i][j];
	printf("%d\n",ans);
	return 0;
}