UVa 798 - Tile Puzzle
Tile Puzzle
http://uva.onlinejudge.org/external/7/798.html
問題概要
100*100までのパズルがあたえられる。
10種類までのピースがあたえられる。
何通りでそのパズルを完成させられますか。
ある場所のピースの種類か向きが異なると、違う完成方法と数える。
解法
DFS
100*100*10*2くらい?
ソース
#include<iostream> #define REP(i,b,n) for(int i=b;i<(int)n;i++) #define rep(i,n) REP(i,0,n) using namespace std; const int N = 100; bool used[N][N]; int W, H, remain[10], cnt, n, w[10], h[10]; bool canPut(int y, int x, int id){ if(y + h[id] > H || x + w[id] > W){ return false; } REP(i, y, y+h[id]){ REP(j, x, x+w[id]){ if(used[i][j])return false; } } return true; } void put(int y, int x, int id, bool v){ REP(i, y, y+h[id]){ REP(j, x, x+w[id]){ used[i][j] = v; } } } void dfs(int y, int x){ if(x == W){ y++; x=0; } if(y == H){ cnt++; return; } if(used[y][x]){ dfs(y, x+1); return; } rep(id, n){ if(remain[id] == 0)continue; rep(d, 2){ bool flag = canPut(y, x, id); if(flag){ put(y, x, id, true); remain[id]--; dfs(y, x+1); remain[id]++; put(y, x, id, false); } if(w[id] == h[id])break; swap(w[id], h[id]); } } } void init(){ rep(i, H){ rep(j, W){ used[i][j] = false; } } cnt = 0; } int main(){ while(cin >> W >> H >> n){ if(W == 0)break; init(); rep(i, n)cin >> remain[i] >> w[i] >> h[i]; dfs(0, 0); cout << cnt << endl; } return 0; }