洛谷P 1022


ひと突きする
タイトルの説明
碁盤のA点には川を渡る卒がいて、目標のB点まで歩く必要があります.歩行のルール:下へ、または右へ.同時に碁盤上のC点には相手の馬があり、その馬がいる点とジャンプして一歩で達する点を相手の馬の制御点と呼ぶ.そのため「馬が川を渡る卒」と呼ばれている.
碁盤は座標で表され、A点(0,0)、B点(n,m)(n,mは20を超えない整数)と同様に馬の位置座標が与えられる必要がある.
今、卒がA点からB点に到達できる経路の数を計算するように要求されます.馬の位置が固定されていると仮定して、卒が一歩歩いて馬が一歩歩いているわけではありません.
にゅうしゅつりょくけいしき
入力形式:
1行の4つのデータで、それぞれB点座標と馬の座標を表します.
出力フォーマット:
すべてのパス・バー数を表すデータ.
入出力サンプル
入力サンプル#1:コピー
6 6 3 3

出力サンプル#1:コピー
6

説明
結果は大きいかもしれません!
どうてきけいかくもんだい
#include
#include
using namespace std;
long long a[30][30];
int xx[8] = {1,1,2,2,-1,-1,-2,-2};
int yy[8] = {2,-2,1,-1,2,-2,1,-1};
int n,m,x,y;
int pd(int x,int y)
{
	if(x>=0&&x<=n&&y>=0&&y<=m)
		return 1;
	return 0;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&x,&y);
	a[x][y] = -1;
	for(int i=0;i<=7;i++)
	{
		int tx = x + xx[i];
		int ty = y + yy[i];
		if(pd(tx,ty))//        
		a[tx][ty] = -1;//          -1  
	}
	if(a[0][0]!=-1)//              
	{
		a[0][0] = 1;//       1  
		for(int i=0;i<=n;i++)
		{
			for(int j=0;j<=m;j++)
			{
				if(a[i][j]!= -1)
				{
					if(i&&a[i-1][j]!=-1) a[i][j] += a[i-1][j]; //        
					if(j&&a[i][j-1]!=-1) a[i][j] += a[i][j-1];
				}
			}
		}
		printf("%lld
",a[n][m]); } else printf(0); }

他の人が書いたもう一つの方法を見つけた.
#include
#include
long long int f[100][100]={{0}},n,m,nn,mm,i,j;
using namespace std;
int main()
{
    cin>>n>>m>>nn>>mm;
    n++,m++,nn++,mm++,f[0][1]=1;//      1
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            if((abs(i-nn)+abs(j-mm)==3)/*                3      */&&(i!=nn)&&(j!=mm)||(i==nn&&j==mm)/*     ,     */)continue;//       
            else{f[i][j]=f[i-1][j]+f[i][j-1];}//       + 
        }
    }
    cout<