AOJ 2091 Petoris
問題概要
あるグリッドにある形のブロックを当てはめることができるか。
できるなら、すべてうまる行の数の最大値をもとめよ。
解法
全探索。
ですが、ブロックの余分な空白をちゃんと詰めないと、
64^4 *4でなくて
128^4*4
になってしまうので注意。
ソース
#include<iostream> #include<string> #include<vector> #include<algorithm> #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 = 64; char t[N][N]; int H, W; class Block{ public: vector<vector<char> > b; void turn(){ vector<vector<char> > newb; rep(j, b[0].size()){ vector<char> tmp; for(int i = b.size()-1; i>= 0; i--){ tmp.push_back(b[i][j]); } newb.push_back(tmp); } b = newb; } }; bool invalid(int y, int x, Block &b){ rep(i, b.b.size()){ rep(j, b.b[i].size()){ if(b.b[i][j] == '.')continue; if(y + i < 0 || y +i >= H || x + j < 0 || x+j >= W)return true; if(t[y+i][x+j] == '#')return true; } } return false; } void put(int y, int x, Block &b){ rep(i, b.b.size()){ rep(j, b.b[i].size()){ if(b.b[i][j] == '.')continue; t[y+i][x+j] = b.b[i][j]; } } } void erase(int y, int x, Block &b){ rep(i, b.b.size()){ rep(j, b.b[i].size()){ if(b.b[i][j] == '.')continue; t[y+i][x+j] = '.'; } } } int calc(){ int ret = 0; rep(i, H){ bool ok = true; rep(j, W){ if(t[i][j] == '.'){ ok = false; break; } } if(ok)ret++; } return ret; } Block b[4]; int main(){ int T; cin >> T; rep(tc, T){ int h, w; cin >> h >> w; b[0].b = vector<vector<char> >(h, vector<char>(w)); rep(i, h){ rep(j, w){ cin >> b[0].b[i][j]; } } rep(i, b[0].b.size()){ if(b[0].b[i] == vector<char>(b[0].b[i].size(), '.')){ b[0].b.erase(b[0].b.begin() + i); i--; } } b[0].turn(); rep(i, b[0].b.size()){ if(b[0].b[i] == vector<char>(b[0].b[i].size(), '.')){ b[0].b.erase(b[0].b.begin() + i); i--; } } REP(i, 1, 4){ b[i] = b[i-1]; b[i].turn(); } cin >> H >> W; rep(i, H){ rep(j, W){ cin >> t[i][j]; } } int maxi = -1; rep(id, 4){ REP(i, 0, H){ REP(j, 0, W){ if(invalid(i, j, b[id]))continue; put(i, j, b[id]); maxi = max(calc(), maxi); erase(i, j, b[id]); } } } cout << maxi << endl; } return 0; }