题目链接:http://acm.fzu.edu.cn/problem.php?pid=2107
Cao Cao was hunted down by thousands of enemy soldiers when he escaped from Hua Rong Dao. Assuming Hua Rong Dao is a narrow aisle (one N*4 rectangle), while Cao Cao can be regarded as one 2*2 grid. Cross general can be regarded as one 1*2 grid.Vertical general can be regarded as one 2*1 grid. Soldiers can be regarded as one 1*1 grid. Now Hua Rong Dao is full of people, no grid is empty.
There is only one Cao Cao. The number of Cross general, vertical general, and soldier is not fixed. How many ways can all the people stand?
There is a single integer T (T≤4) in the first line of the test data indicating that there are T test cases.
Then for each case, only one integer N (1≤N≤4) in a single line indicates the length of Hua Rong Dao.
Here are 2 possible ways for the Hua Rong Dao 2*4.
给出n(1≤n≤4)然后在一个n * 4的格子上放矩形,必须放一个2*2的(为题目背景下的曹操),然后剩余的位置要用三种矩形拼接。
PS:
先枚举曹操的位置,然后用回溯的方式枚举出所有可能,计算总数。
打表代码:(系转自:http://www.shangxueba.com/jingyan/1818854.html)
#include<stdio.h> #include<string.h> const int N = 10; const int d[4][2] = { {0, 0}, {0, 1}, {1, 0}, {1, 1} }; const int dir[3][3][2] = { { {0, 1}, {0, 0} }, { {1, 0}, {0, 0} }, { {0, 0} } }; const int cnt[3] = {2, 2, 1}; int r, v[N][N], tmp; const int c = 4; bool isInsert(int k, int x, int y) { for (int i = 0; i< cnt[k]; i++) { int p = x + dir[k][i][0], q = y + dir[k][i][1]; if (p<= 0 || p >r) return false; if (q<= 0 || q >c) return false; if (v[p][q]) return false; } return true; } void clear(int k, int x, int y, int t) { for (int i = 0; i< cnt[k]; i++) { int p = x + dir[k][i][0], q = y + dir[k][i][1]; v[p][q] = t; } } void dfs(int x, int y) { if (y >c) x = x + 1, y = 1; if (x == r + 1) { tmp++; return; } if (v[x][y]) dfs(x, y + 1); for (int i = 0; i< 3; i++) { if (isInsert(i, x, y)) { clear(i, x, y, 1); dfs(x, y + 1); clear(i, x, y, 0); } } } int find(int x, int y) { memset(v, 0, sizeof(v)); for (int i = 0; i< 4; i++) v[x + d[i][0]][y + d[i][1]] = 1; tmp = 0; dfs(1, 1); return tmp; } int solve() { int ans = 0; for (int i = 1; i< r; i++) { for (int j = 1; j< c; j++) { ans += find(i, j); } } return ans; } int main () { int t[10]; for (r = 1; r<= 4; r++) { t[r] = solve(); } int cas, n; scanf("%d", &cas); while (cas--) { scanf("%d", &n); printf("%d\n", t[n]); } return 0; }
代码如下:
#include <cstdio> int main() { int t; int n; scanf("%d",&t); while(t--) { scanf("%d",&n); if(n==1) puts("0"); else if(n==2) puts("18"); else if(n==3) puts("284"); else if(n==4) puts("4862"); } return 0; }
FZU Problem 2107 Hua Rong Dao (打表 dfs啊)
原文地址:http://blog.csdn.net/u012860063/article/details/41751167