Problem H.Dominoes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17    Accepted Submission(s): 12



Problem Description

Orz likes to play dominoes. Now giving an n\*m chessboard and k dominoes whose size are 1\*2, Orz finds that there is exactly one grid empty, so that he can move dominoes without overlapping them. An initial situation is given, he wants to know how many final situation could be achieved, except the initial situation. Note every domino is different, as they have their own serial number. Since the answer may be very large, please output the answer modulo 1000000009.

Input

There will be multiple test cases. For each test case:

The first line contains three integers: n,m,k(n≤9,m≤10000).

The following k lines, each line contains four integers: a \ b \ c \ d, indicating that this domino occupies (a, b) and (c, d). 

The input guarantees that the domino does not overlap, and there is exactly one empty grid.

Output

For each test cases, output the answer modulo 1000000009.

Sample Input

5 5 12

1 1 2

1 1 2

2 2 1

3 2 3

1 4 1

5 2 4

2 5 3

4 3 5

3 1 3

2 4 1

4 2 5

1 5 2

4 3 5

3 4 4

5 4 4

5 5 5

Sample Output

8

解题思路:找规律可发现一块多米诺骨牌最多只会动一次除非往反方向走,又因为骨牌动一下等于空格向上、下、左、右方向移动两格,所以直接宽度优先搜索空格可以到的位置有多少个就是有多少解。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
const int dir[4][2]={1,0,-1,0,0,1,0,-1};
queue<pii> q;
int n,m,k,ans; // 撑死 90000,不需mod
int mp[20][10100];

void init()
{
ans=0;
mem(mp,0);
while(!q.empty()) q.pop();
}

void bfs()
{
int flag=1;
for(int i=1;i<=n&&flag;i++)
for(int j=1&&flag;j<=m;j++)
if(!mp[i][j])
{
flag=0;
q.push(make_pair(i,j));
}

int x,y;
while(!q.empty())
{
x=q.front().first, y=q.front().second; q.pop();
for(int i=0;i<4;i++)
{
// mp[x+dir[i][0]][y+dir[i][1]]!=0 原本以为不用加,后来发现少考虑一种情况:空格满图“跑”的时候,回到第一次的空格(若不加此条件)就死循环了
if(mp[x+dir[i][0]][y+dir[i][1]]!=0 && mp[x+dir[i][0]][y+dir[i][1]]==mp[x+dir[i][0]*2][y+dir[i][1]*2])
{
ans++;
q.push(make_pair(x+dir[i][0]*2,y+dir[i][1]*2));
}
}
}

}

int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
init();
int a,b,c,d;
for(int i=0,th=1;i<k;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
mp[a][b]=mp[c][d]=th++;
}
bfs();
printf("%d\n",ans);
}

return 0;
}