hihocoder 1191 小W與網格 (組合數)

_TCgogogo_發表於2015-07-27


時間限制:1000ms
單點時限:1000ms
記憶體限制:256MB

描述

給定一個n*m的網格,左上角(1, 1),右下角(n, m)。

小w在(i, j),他會從"上左下右"四個方向中選定兩個不同但正交的方向,然後他只能沿著這兩個方向走,直到他走出網格。

小w想知道有多少種不同的走法。

兩個走法不同當且僅當所經過的格子的集合不同。

輸入

輸入包含多組資料。

每組資料一行四個整數n, m, i, j。(1 <= i <= n <= 100, 1 <= j <= m <= 100)

輸出

對於每組資料,輸出一個整數表示方案數,答案對1000000007取模。

樣例解釋

無論怎麼走,要麼覆蓋一格,要麼覆蓋兩格。

樣例輸入2 1 1 1樣例輸出2

題目連結:http://hihocoder.com/problemset/problem/1191


題目分析:又是這種方格里面走路方案數的問題,任意兩格(x1, y1) ,(x2, y2)間走路的方案數為c[abs(x1 - x2)][abs(x1 - x2) + abs(y1 - y2)],c是組合數,那麼對於這題,我要求的就是(i,j)這個點到四邊的方案數和,列舉一下邊界用上面的公式算就可以了


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 205;
int const MOD = 1e9 + 7;
int c[MAX][MAX];

void pre()
{
    c[0][0] = 1;
    for(int i = 1; i <= 200; i++)
    {
        c[i][0] = 1;
        for(int j = 1; j <= 200; j++)
            c[i][j] = (c[i - 1][j] % MOD + c[i - 1][j - 1] % MOD) % MOD;
    }
}

int main()
{
    int n, m, i, j;
    pre();
    while(scanf("%d %d %d %d", &n, &m, &i, &j) != EOF)
    {
        int ans = 0;
        for(int x = 1; x <= n; x++)
        {
            for(int y = 1; y <= m; y++)
            {
                if(x == 1 || x == n || y == 1 || y == m)
                {
                    int xx = abs(x - i);
                    int yy = abs(y - j);
                    ans = (ans % MOD + c[xx + yy][xx] % MOD) % MOD;
                }
            }
        }
        printf("%d\n", ans);
    }
}



相關文章