Problem:
ジグソーパズル
子供から大人まで脳トレ系パズルゲームが流行しています。我々も遅れを取らぬよう、パズルゲームを作ってみんなで遊ぶことにしました。
我々が考えたのはジグソーパズルのゲームで、未完成の部分を埋めるのに必要なピースを選ぶというものです。図 1 (a) はパズルの枠の例です。黒が埋まっている部分、白が未完成の部分です。このパズルを完成するのに使えるピースが図 1 (b) のように与えられます。この中から、枠の白い部分を埋めることができる黒いピースを 1 つ以上選択します。例えば、図 2 の選択例 1 のような組み合わせなら正解となります。一方、選択例 2 のような組み合わせではパズルは完成しないので不正解となります。また、選択したピースが余ってしまう場合も不正解です。このように、プレイヤーは適切なピースを選択することでゲームをクリアします。
そこでこのパズルゲームで用いる判定プログラムを開発することになりました。未完成のパズル、ピースの候補、そしてプレイヤーが選んだピースの組み合わせを入力とし、プレイヤーが適切なピースを選ぶことができていれば YES を、そうでなければ NO と出力するプログラムを作成してください。
この問題では、パズルの枠は
H × W
の配列で表し、未完成の部分を . (半角ピリオド)、完成している部分を # (半角シャープ)によって与えます。パズルの枠の大きさは最大
20 × 20
とします。また、各ピースは
h × w
の配列で表し、ピースを構成する部分を # 、そうでない部分を . によって与えます。与えられる各ピースは、元の状態から 90 度、180 度、270 度だけ回転することができます。また、各ピースの大きさは最大
20 × 20
とし、与えられるピースの数
n
は最大 10 とします。
Input
複数のデータセットが与えられます。各データセットは以下の形式で与えられます。
H
W
g
1,1
g
1,2
...
g
1,W
g
2,1
g
2,2
...
g
2,W
:
g
H,1
g
H,2
...
g
H,W
n
h
1
w
1
c1
1,1
c1
1,2
...
c1
1,w
1
c1
2,1
c1
2,2
...
c1
2,w
1
:
c1
h
1
,1
c1
h
1
,2
...
c1
h
1
,w
1
:
:
h
n
w
n
cn
1,1
cn
1,2
...
cn
1,w
n
cn
2,1
cn
2,2
...
cn
2,w
n
:
cn
h
n
,1
cn
h
n
,2
...
cn
h
n
,w
n
p
k
1
t
1
t
2
...
t
k
1
k
2
t
1
t
2
...
t
k
2
:
k
p
t
1
t
2
...
t
k
p
1 行目に、パズルの枠の大きさ
H
(縦) と
W
(横) が与えられます。
2 行目に、文字
g
i,j
(
.
または
#
) からなりパズルの盤面を表す 1 行
W
文字の文字列が
H
行与えられます。
続いてピースの数
n
、
n
個のピースの情報が与えられます。各ピースの情報として、
l
番目のピースの配列のサイズ
h
l
(縦) と
w
l
(横)、
l
番目のピースの配列が与えられます。
l
番目のピースの配列として文字
cl
i,j
(
.
または
#
) からなる 1 行
w
l
文字の文字列が
h
l
行与えられます。
続いてプレイヤーの人数
p
、
i
番目のプレイヤーの選択したピースの数
k
i
と選択したピースの番号
t
j
が与えられます。
入力は２つの 0 を含む行で終了します。データセットの数は 10 を超えません。
Output
各データセットごとに、
i
番目のプレイヤーが選択したピースの正否 YES または NO を
i
行目に出力してください。
Sample Input
14 20
####################
###.............####
####..........######
#######.....########
########.....#######
###..###......######
###..####......#####
#########......#####
###########.....####
############.....###
###.########......##
###.#######...###.##
##...###....#####.##
####################
10
12 15
#############..
.##########....
....#####......
.....#####.....
.....######....
......######...
......######...
........#####..
.........#####.
.........######
........###...#
.....####.....#
3 3
#..
###
#..
2 2
##
##
4 10
....#####.
....######
...###...#
####.....#
6 5
....#
..###
#####
##.##
#..##
#..#.
6 4
...#
.###
####
##.#
##.#
#...
2 6
######
.#####
2 7
..#####
#######
2 13
#############
.##########..
6 9
#####....
.######..
.######..
..######.
...#####.
....#####
8
3 1 2 3
4 1 2 3 4
7 2 3 4 5 6 7 8
5 2 3 10 7 8
6 2 3 9 5 6 4
8 2 3 4 6 9 5 4 10
4 4 5 6 9
5 10 2 3 4 9
0 0
Output for the Sample Input
YES
NO
YES
NO
YES
NO
NO
YES

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int grid_h, grid_w, piece_count, piece_h[40], piece_w[40], piece_size[40];
int selected_count, selected_pieces[10];
char grid[20][21], pieces[40][20][21];
bool covered[20][20];

bool solve(int current_piece) {
    if (current_piece == selected_count) return true;
    memset(covered, 0, sizeof(covered));
    for (int i = 0; i < grid_h; ++i) {
        for (int j = 0; j < grid_w; ++j) {
            if (grid[i][j] == '.' && !covered[i][j]) {
                for (int k = current_piece; k < selected_count; ++k) {
                    for (int rotation = 0; rotation < 4; ++rotation) {
                        int piece_idx = selected_pieces[k] + rotation * piece_count;
                        for (int y = max(0, i - piece_h[piece_idx] + 1); y <= i && y + piece_h[piece_idx] <= grid_h; ++y) {
                            for (int x = max(0, j - piece_w[piece_idx] + 1); x <= j && x + piece_w[piece_idx] <= grid_w; ++x) {
                                bool fits = true;
                                for (int a = 0; a < piece_h[piece_idx] && fits; ++a) {
                                    for (int b = 0; b < piece_w[piece_idx] && fits; ++b) {
                                        if (pieces[piece_idx][a][b] == '#' && grid[y + a][x + b] == '#') {
                                            fits = false;
                                        }
                                    }
                                }
                                if (fits) {
                                    for (int a = 0; a < piece_h[piece_idx]; ++a) {
                                        for (int b = 0; b < piece_w[piece_idx]; ++b) {
                                            if (pieces[piece_idx][a][b] == '#') {
                                                covered[y + a][x + b] = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (!covered[i][j]) return false;
            }
        }
    }

    for (int rotation = 0; rotation < 4; ++rotation) {
        int piece_idx = selected_pieces[current_piece] + rotation * piece_count;
        for (int y = 0; y + piece_h[piece_idx] <= grid_h; ++y) {
            for (int x = 0; x + piece_w[piece_idx] <= grid_w; ++x) {
                bool fits = true;
                for (int a = 0; a < piece_h[piece_idx] && fits; ++a) {
                    for (int b = 0; b < piece_w[piece_idx] && fits; ++b) {
                        if (grid[y + a][x + b] == '#' && pieces[piece_idx][a][b] == '#') {
                            fits = false;
                        }
                    }
                }
                if (fits) {
                    for (int a = 0; a < piece_h[piece_idx]; ++a) {
                        for (int b = 0; b < piece_w[piece_idx]; ++b) {
                            if (pieces[piece_idx][a][b] == '#') {
                                grid[y + a][x + b] = '#';
                            }
                        }
                    }
                    bool result = solve(current_piece + 1);
                    for (int a = 0; a < piece_h[piece_idx]; ++a) {
                        for (int b = 0; b < piece_w[piece_idx]; ++b) {
                            if (pieces[piece_idx][a][b] == '#') {
                                grid[y + a][x + b] = '.';
                            }
                        }
                    }
                    if (result) return true;
                }
            }
        }
    }
    return false;
}

int main() {
    while (cin >> grid_h >> grid_w, grid_h) {
        int empty_cells = 0;
        for (int i = 0; i < grid_h; ++i) {
            cin >> grid[i];
            for (int j = 0; j < grid_w; ++j) {
                if (grid[i][j] == '.') empty_cells++;
            }
        }
        cin >> piece_count;
        for (int i = 0; i < piece_count; ++i) {
            cin >> piece_h[i] >> piece_w[i];
            piece_size[i] = 0;
            for (int j = 0; j < piece_h[i]; ++j) {
                cin >> pieces[i][j];
                for (int k = 0; k < piece_w[i]; ++k) {
                    if (pieces[i][j][k] == '#') piece_size[i]++;
                }
            }
            int current = i;
            for (int j = 0; j < 3; ++j) {
                int rotated = current + piece_count;
                piece_h[rotated] = piece_w[current];
                piece_w[rotated] = piece_h[current];
                piece_size[rotated] = piece_size[current];
                for (int y = 0; y < piece_h[current]; ++y) {
                    for (int x = 0; x < piece_w[current]; ++x) {
                        pieces[rotated][x][piece_h[current] - y - 1] = pieces[current][y][x];
                    }
                }
                current = rotated;
            }
        }
        int queries;
        cin >> queries;
        while (queries--) {
            cin >> selected_count;
            int total_pieces = 0;
            for (int i = 0; i < selected_count; ++i) {
                cin >> selected_pieces[i];
                selected_pieces[i]--;
                total_pieces += piece_size[selected_pieces[i]];
            }
            sort(selected_pieces, selected_pieces + selected_count, [&](int a, int b) {
                return piece_size[a] > piece_size[b];
            });
            cout << (total_pieces == empty_cells && solve(0) ? "YES" : "NO") << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 3368
final_rank: 12

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

using bs = bitset<400>;

struct piece {
    int h,w;
    int i,j;
    bs bit;
    piece() {}
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int h,w;
    while (cin >> h >> w, h+w) {
        bs puzzle;
        int rem = 0;
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w; ++j) {
                char c; cin >> c;
                if (c == '#') {
                    puzzle[i*w+j] = 1;
                }
                else {
                    rem++;
                }
            }
        }
        using A = array<piece, 4>;
        int m; cin >> m;
        vector<A> v(m);
        vector<int> cnt(m);
        for (int i = 0; i < m; ++i) {
            int hh,ww; cin >> hh >> ww;
            vector<vector<char>> s(hh, vector<char>(ww));
            for (int j = 0; j < hh; ++j) {
                for (int k = 0; k < ww; ++k) {
                    cin >> s[j][k];
                    if (s[j][k] == '#') cnt[i]++;
                }
            }
            for (int j = 0; j < 4; ++j) {
                v[i][j].h = hh; v[i][j].w = ww;
                bool done = false;
                for (int k = 0; k < hh; ++k) {
                    for (int l = 0; l < ww; ++l) {
                        if (s[k][l] == '#') {
                            if (!done) {
                                v[i][j].i = k;
                                v[i][j].j = l;
                                done = true;
                            }
                            v[i][j].bit[k*w+l] = 1;
                        }
                    }
                }
                {
                    vector<vector<char>> ns(ww, vector<char>(hh));
                    for (int k = 0; k < hh; ++k) {
                        for (int l = 0; l < ww; ++l) {
                            ns[l][k] = s[hh-1-k][l];
                        }
                    }
                    swap(s, ns);
                    swap(hh, ww);
                }
            }
        }
        vector<int> sum(1<<m);
        for (int i = 0; i < (1<<m); ++i) {
            for (int j = 0; j < m; ++j) {
                if ((1<<j)&i) sum[i] += cnt[j];
            }
        }

        vector<unordered_set<bs>> bfs(1<<m);
        bfs[0].insert(puzzle);
        for (int i = 0; i < (1<<m); ++i) {
            if (sum[i] >= rem) continue;
            for (auto p : bfs[i]) {
                bool done = false;
                int x = -1, y = -1;
                for (int j = 0; j < h; ++j) {
                    for (int k = 0; k < w; ++k) {
                        if (!p[j*w+k]) {
                            done = true;
                            x = j, y = k;
                            break;
                        }
                    }
                    if (done) break;
                }

                for (int j = 0; j < m; ++j) {
                    if ((1<<j)&i) continue;
                    for (int k = 0; k < 4; ++k) {
                        if (x < v[j][k].i) continue;
                        if (y < v[j][k].j) continue;
                        if (x + (v[j][k].h-1-v[j][k].i) >= h) continue;
                        if (y + (v[j][k].w-1-v[j][k].j) >= w) continue;
                        auto u = p & (v[j][k].bit << (y-v[j][k].j + w*(x-v[j][k].i)));
                        if (u.none()) {
                            auto uu = p | (v[j][k].bit << (y-v[j][k].j + w*(x-v[j][k].i)));
                            bfs[(1<<j)|i].insert(uu);
                        }
                    }
                }
            }
        }

        int q; cin >> q;
        while (q--) {
            int n; cin >> n;
            int bit = 0;
            for (int i = 0; i < n; ++i) {
                int k; cin >> k; k--;
                bit += (1<<k);
            }
            if (sum[bit] == rem and bfs[bit].size()) {
                cout << "YES" << "\n";
            }
            else {
                cout << "NO" << "\n";
            }
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 4112
final_rank: 1

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000001
#define Inf64 2000000000000000001

void rotate(vector<string> &s){
	int h = s.size();
	int w = s[0].size();
	vector<string> x(w,string(h,'.'));
	rep(i,h){
		rep(j,w){
			x[j][i] = s[h-1-i][j];
		}
	}
	s = x;
}
set<int> ok;
set<pair<vector<string>,int>> used;

bool check(vector<string> a,vector<string> b,int x,int y){
	if(x<0||y<0||x+b.size()>a.size()||y+b[0].size()>a[0].size())return false;
	rep(i,b.size()){
		rep(j,b[i].size()){
			if(b[i][j]=='#' && a[x+i][y+j]=='#')return false;
		}
	}
	return true;
}

void go(vector<string> &a,vector<string> b,int x,int y){
	
	rep(i,b.size()){
		rep(j,b[i].size()){
			if(b[i][j]=='#')a[x+i][y+j]='#';
		}
	}
	
}

void dfs(vector<string> s,vector<vector<string>> ss,int cur){

	if(used.count(make_pair(s,cur)))return;
	used.emplace(s,cur);
	if(s==vector<string>(s.size(),string(s[0].size(),'#'))){
		ok.insert(cur);
		return;
	}
	int ii,jj;
	rep(i,s.size()){
		rep(j,s[i].size()){
			if(s[i][j]=='.'){
				ii = i,jj = j;
				goto L;
			}
		}
	}
	L:;
	rep(i,ss.size()){
		if((cur>>i)&1)continue;
		rep(j,4){
			auto ns = s;
			int jjj;
			rep(k,ss[i][0].size()){
				if(ss[i][0][k]=='#'){
					jjj = k;
					break;
				}
			}
			//cout<<jj<<','<<ii<<','<<jjj<<endl;
			if(check(ns,ss[i],ii,jj-jjj)){
				go(ns,ss[i],ii,jj-jjj);
				dfs(ns,ss,cur|(1<<i));
			}
			rotate(ss[i]);
		}
	}
		
}

int main(){
	
	while(true){
		int h,w;
		cin>>h>>w;
		if(h==0)break;
		vector<string> s(h);
		rep(i,h)cin>>s[i];
		int n;
		cin>>n;
		vector<vector<string>> ss(n);
		rep(i,n){
			int a,b;
			cin>>a>>b;
			ss[i].resize(a);
			rep(j,a)cin>>ss[i][j];
		}
		rep(i,n){
			rep(j,4){
				rotate(ss[i]);
				while(ss[i].back()==string(ss[0].size(),'.'))ss[i].pop_back();
			}
		}
		
		ok.clear();
		used.clear();
		dfs(s,ss,0);
		
		int p;
		cin>>p;
		rep(i,p){
			int k;
			cin>>k;
			
			int cur =0;
			rep(j,k){
				int t;
				cin>>t;
				cur |= 1<<(t-1);
			}
			if(ok.count(cur))cout<<"YES"<<endl;
			else cout<<"NO"<<endl;
			
			
		}
		
	}
	
    return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 7556
final_rank: 8

code_snippet: #include<iostream>
#include<map>

#define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

using namespace std;

int puzzle_height, puzzle_width;

class Puzzle {
public:

    int used_piece_state;
    char grid[20][20];

    bool operator<(const Puzzle &p) const {
        for (int i = 0; i < puzzle_height; i++) {
            for (int j = 0; j < puzzle_width; j++) {
                if (grid[i][j] == p.grid[i][j])continue;
                return grid[i][j] < p.grid[i][j];
            }
        }
        return used_piece_state < p.used_piece_state;
    }
};

Puzzle puzzle;
map<Puzzle, bool> is_searched_puzzle;


char pieces[40][20][20];

int piece_h[40], piece_w[40];
int num_pieces;

bool result[1024];

#if READ_FROM_FILE
void input(std::ifstream &ifs);
#else
void input();
#endif

void init();

void rotate(int, int);

void dfs(int, int);

bool can_append(int, int, int);

void append_piece(int, int, int);

void remove_piece(int, int, int);


int main() {
#if READ_FROM_FILE
    std::ifstream ifs("../test0.txt");
#endif
    int used_piece_state;
#if READ_FROM_FILE
    while (ifs >> puzzle_height >> puzzle_width) {
#else
        while(cin>>puzzle_height>>puzzle_width){
#endif
        int num_players = 0;
        if (puzzle_height == 0 && puzzle_width == 0)break;

#if READ_FROM_FILE
        input(ifs);
#else
        input();
#endif
        init();

        puzzle.used_piece_state = 0;
        dfs(0, 0);

#if READ_FROM_FILE
        ifs >> num_players;
#else
        cin>>num_players;
#endif
        for (int i = 0; i < num_players; i++) {
            int num_selected_pieces = 0;
#if READ_FROM_FILE
            ifs >> num_selected_pieces;
#else
            cin>>num_selected_pieces;
#endif
            used_piece_state = 0;
            for (int j = 0; j < num_selected_pieces; j++) {
                int idx = 0;
#if READ_FROM_FILE
                ifs >> idx;
#else
                cin>>idx;
#endif
                idx--;
                used_piece_state += (1 << idx);
            }

            if (result[used_piece_state])cout << "YES" << endl;
            else cout << "NO" << endl;
        }

    }
    return 0;
}


void dfs(int y, int x) {

    int tmp = puzzle.used_piece_state;
    bool is_solved = true;

    for (int i = 0; i < puzzle_height; i++) {
        for (int j = 0; j < puzzle_width; j++) {
            if (puzzle.grid[i][j] != '#'){
                is_solved = false;
            }
        }
    }
    if (is_solved) {
        result[puzzle.used_piece_state] = true;
        return;
    }

    is_searched_puzzle[puzzle] = true;

    for (int i = 0; i < num_pieces; i++) {
        if (((puzzle.used_piece_state >> i) & 1) == 1){
            continue;
        }
        for (int j = 0; j < 4; j++) {

            if (!can_append(y, x, 4 * i + j)){
                continue;
            }

            puzzle.used_piece_state += (1 << i);

            append_piece(y, x, 4 * i + j);

            if (!is_searched_puzzle[puzzle]){
                dfs(y, x);
            }

            remove_piece(y, x, 4 * i + j);
            puzzle.used_piece_state = tmp;
        }
    }

    if (puzzle.grid[y][x] == '#'){
        dfs((x + 1 == puzzle_width ? y + 1 : y), (x + 1 == puzzle_width ? 0 : x + 1));
    }
}


void rotate(int a, int b) {
    for (int i = 0; i < piece_h[a]; i++) {
        for (int j = 0; j < piece_w[a]; j++) {
            pieces[a][i][j] = pieces[b][j][piece_h[a] - i - 1];
        }
    }
}


void init() {
    is_searched_puzzle.clear();
    for (int i = 0; i < 1024; i++){
        result[i] = false;
    }
}

#if READ_FROM_FILE
void input(std::ifstream &ifs) {
#else
    void input(){
#endif
    for (int i = 0; i < 20; i++)
        for (int j = 0; j < 20; j++){
            puzzle.grid[i][j] = '.';
        }

    string str;
    for (int i = 0; i < puzzle_height; i++) {
#if READ_FROM_FILE
        ifs >> str;
#else
        cin>>str;
#endif
        for (int j = 0; j < puzzle_width; j++) {
            puzzle.grid[i][j] = str[j];
        }
    }
#if READ_FROM_FILE
    ifs >> num_pieces;
#else
    cin>>num_pieces;
#endif
    for (int k = 0; k < num_pieces; k++) {
#if READ_FROM_FILE
        ifs >> piece_h[k * 4] >> piece_w[k * 4];
#else
        cin>>piece_h[k*4]>>piece_w[k*4];
#endif
        for (int i = 0; i < piece_h[k * 4]; i++) {
#if READ_FROM_FILE
            ifs >> str;
#else
            cin>>str;
#endif
            for (int j = 0; j < piece_w[k * 4]; j++) {
                pieces[k * 4][i][j] = str[j];
            }
        }
        for (int i = 1; i < 4; i++) {
            piece_h[k * 4 + i] = piece_w[k * 4 + i - 1];
            piece_w[k * 4 + i] = piece_h[k * 4 + i - 1];
            rotate(k * 4 + i, k * 4 + i - 1);
        }
    }
}


bool can_append(int y, int x, int piece_idx) {
    if (y + piece_h[piece_idx] > puzzle_height || x + piece_w[piece_idx] > puzzle_width){
        return false;
    }
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#' && puzzle.grid[i][j] == '#'){
                return false;
            }
        }
    }
    return true;
}


void append_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '#';
            }
        }
    }
}


void remove_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '.';
            }
        }
    }
}
accuracy: 1
time_ms: 320
memory_kb: 8432
final_rank: 9

code_snippet: #include<iostream>
#include<map>

#define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

using namespace std;

int puzzle_height, puzzle_width;

class Puzzle {
public:

    int used_piece_state;
    char grid[20][20];

    bool operator<(const Puzzle &p) const {
        for (int i = 0; i < puzzle_height; i++) {
            for (int j = 0; j < puzzle_width; j++) {
                if (grid[i][j] == p.grid[i][j])continue;
                return grid[i][j] < p.grid[i][j];
            }
        }
        return used_piece_state < p.used_piece_state;
    }
};

Puzzle puzzle;
map<Puzzle, bool> is_searched_puzzle;


char pieces[40][20][20];

int piece_h[40], piece_w[40];
int num_pieces;

bool result[2048];

#if READ_FROM_FILE
void input(std::ifstream &ifs);
#else
void input();
#endif

void init();

void rotate(int, int);

void dfs(int, int);

bool can_append(int, int, int);

void append_piece(int, int, int);

void remove_piece(int, int, int);


int main() {
#if READ_FROM_FILE
    std::ifstream ifs("../test0.txt");
#endif
    int used_piece_state;
#if READ_FROM_FILE
    while (ifs >> puzzle_height >> puzzle_width) {
#else
        while(cin>>puzzle_height>>puzzle_width){
#endif
        int num_players = 0;
        if (puzzle_height == 0 && puzzle_width == 0)break;

#if READ_FROM_FILE
        input(ifs);
#else
        input();
#endif
        init();

        puzzle.used_piece_state = 0;
        dfs(0, 0);

#if READ_FROM_FILE
        ifs >> num_players;
#else
        cin>>num_players;
#endif
        for (int i = 0; i < num_players; i++) {
            int num_selected_pieces = 0;
#if READ_FROM_FILE
            ifs >> num_selected_pieces;
#else
            cin>>num_selected_pieces;
#endif
            used_piece_state = 0;
            for (int j = 0; j < num_selected_pieces; j++) {
                int idx = 0;
#if READ_FROM_FILE
                ifs >> idx;
#else
                cin>>idx;
#endif
                idx--;
                used_piece_state += (1 << idx);
            }

            if (result[used_piece_state])cout << "YES" << endl;
            else cout << "NO" << endl;
        }

    }
    return 0;
}


void dfs(int y, int x) {

    int tmp = puzzle.used_piece_state;
    bool is_solved = true;

    for (int i = 0; i < puzzle_height; i++) {
        for (int j = 0; j < puzzle_width; j++) {
            if (puzzle.grid[i][j] != '#'){
                is_solved = false;
            }
        }
    }
    if (is_solved) {
        result[puzzle.used_piece_state] = true;
        return;
    }

    is_searched_puzzle[puzzle] = true;

    for (int i = 0; i < num_pieces; i++) {
        if (((puzzle.used_piece_state >> i) & 1) == 1){
            continue;
        }
        for (int j = 0; j < 4; j++) {

            if (!can_append(y, x, 4 * i + j)){
                continue;
            }

            puzzle.used_piece_state += (1 << i);

            append_piece(y, x, 4 * i + j);

            if (!is_searched_puzzle[puzzle]){
                dfs(y, x);
            }

            remove_piece(y, x, 4 * i + j);
            puzzle.used_piece_state = tmp;
        }
    }

    if (puzzle.grid[y][x] == '#'){
        dfs((x + 1 == puzzle_width ? y + 1 : y), (x + 1 == puzzle_width ? 0 : x + 1));
    }
}


void rotate(int a, int b) {
    for (int i = 0; i < piece_h[a]; i++) {
        for (int j = 0; j < piece_w[a]; j++) {
            pieces[a][i][j] = pieces[b][j][piece_h[a] - i - 1];
        }
    }
}


void init() {
    is_searched_puzzle.clear();
    for (int i = 0; i < 2048; i++){
        result[i] = false;
    }
}

#if READ_FROM_FILE
void input(std::ifstream &ifs) {
#else
    void input(){
#endif
    for (int i = 0; i < 20; i++)
        for (int j = 0; j < 20; j++){
            puzzle.grid[i][j] = '.';
        }

    string str;
    for (int i = 0; i < puzzle_height; i++) {
#if READ_FROM_FILE
        ifs >> str;
#else
        cin>>str;
#endif
        for (int j = 0; j < puzzle_width; j++) {
            puzzle.grid[i][j] = str[j];
        }
    }
#if READ_FROM_FILE
    ifs >> num_pieces;
#else
    cin>>num_pieces;
#endif
    for (int k = 0; k < num_pieces; k++) {
#if READ_FROM_FILE
        ifs >> piece_h[k * 4] >> piece_w[k * 4];
#else
        cin>>piece_h[k*4]>>piece_w[k*4];
#endif
        for (int i = 0; i < piece_h[k * 4]; i++) {
#if READ_FROM_FILE
            ifs >> str;
#else
            cin>>str;
#endif
            for (int j = 0; j < piece_w[k * 4]; j++) {
                pieces[k * 4][i][j] = str[j];
            }
        }
        for (int i = 1; i < 4; i++) {
            piece_h[k * 4 + i] = piece_w[k * 4 + i - 1];
            piece_w[k * 4 + i] = piece_h[k * 4 + i - 1];
            rotate(k * 4 + i, k * 4 + i - 1);
        }
    }
}


bool can_append(int y, int x, int piece_idx) {
    if (y + piece_h[piece_idx] > puzzle_height || x + piece_w[piece_idx] > puzzle_width){
        return false;
    }
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#' && puzzle.grid[i][j] == '#'){
                return false;
            }
        }
    }
    return true;
}


void append_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '#';
            }
        }
    }
}


void remove_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '.';
            }
        }
    }
}
accuracy: 1
time_ms: 320
memory_kb: 8332
final_rank: 7

code_snippet: #include<iostream>
#include<map>

#define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

using namespace std;

int puzzle_height, puzzle_width;

class Puzzle {
public:

    int used_piece_state;
    char grid[20][20];

    bool operator<(const Puzzle &p) const {
        for (int i = 0; i < puzzle_height; i++) {
            for (int j = 0; j < puzzle_width; j++) {
                if (grid[i][j] == p.grid[i][j])continue;
                return grid[i][j] < p.grid[i][j];
            }
        }
        return used_piece_state < p.used_piece_state;
    }
};

Puzzle puzzle;
map<Puzzle, bool> is_searched_puzzle;


char pieces[40][20][20];

int piece_h[40], piece_w[40];
int num_pieces;

bool result[2048];

#if READ_FROM_FILE
void input(std::ifstream &ifs);
#else
void input();
#endif

void init();

void rotate(int, int);

void dfs(int, int);

bool can_append(int, int, int);

void append_piece(int, int, int);

void remove_piece(int, int, int);


int main() {
#if READ_FROM_FILE
    std::ifstream ifs("../test0.txt");
#endif
    int used_piece_state;
#if READ_FROM_FILE
    while (ifs >> puzzle_height >> puzzle_width) {
#else
        while(cin>>puzzle_height>>puzzle_width){
#endif
        int num_players = 0;
        if (puzzle_height == 0 && puzzle_width == 0)break;

#if READ_FROM_FILE
        input(ifs);
#else
        input();
#endif
        init();

        puzzle.used_piece_state = 0;
        dfs(0, 0);

#if READ_FROM_FILE
        ifs >> num_players;
#else
        cin>>num_players;
#endif
        for (int i = 0; i < num_players; i++) {
            int num_selected_pieces = 0;
#if READ_FROM_FILE
            ifs >> num_selected_pieces;
#else
            cin>>num_selected_pieces;
#endif
            used_piece_state = 0;
            for (int j = 0; j < num_selected_pieces; j++) {
                int idx = 0;
#if READ_FROM_FILE
                ifs >> idx;
#else
                cin>>idx;
#endif
                idx--;
                used_piece_state += (1 << idx);
            }

            if (result[used_piece_state])cout << "YES" << endl;
            else cout << "NO" << endl;
        }

    }
    return 0;
}


void dfs(int y, int x) {

    int tmp = puzzle.used_piece_state;
    bool is_solved = true;

    for (int i = 0; i < puzzle_height; i++) {
        for (int j = 0; j < puzzle_width; j++) {
            if (puzzle.grid[i][j] != '#'){
                is_solved = false;
            }
        }
    }
    if (is_solved) {
        result[puzzle.used_piece_state] = true;
        return;
    }

    is_searched_puzzle[puzzle] = true;

    for (int i = 0; i < num_pieces; i++) {
        if ((puzzle.used_piece_state >> i) & 1 == 1){
            continue;
        }
        for (int j = 0; j < 4; j++) {

            if (can_append(y, x, 4 * i + j) == false){
                continue;
            }

            puzzle.used_piece_state += (1 << i);

            append_piece(y, x, 4 * i + j);

            if (is_searched_puzzle[puzzle] == false){
                dfs(y, x);
            }

            remove_piece(y, x, 4 * i + j);
            puzzle.used_piece_state = tmp;
        }
    }

    if (puzzle.grid[y][x] == '#'){
        dfs((x + 1 == puzzle_width ? y + 1 : y), (x + 1 == puzzle_width ? 0 : x + 1));
    }
}


void rotate(int a, int b) {
    for (int i = 0; i < piece_h[a]; i++) {
        for (int j = 0; j < piece_w[a]; j++) {
            pieces[a][i][j] = pieces[b][j][piece_h[a] - i - 1];
        }
    }
}


void init() {
    is_searched_puzzle.clear();
    for (int i = 0; i < 2048; i++){
        result[i] = false;
    }
}

#if READ_FROM_FILE
void input(std::ifstream &ifs) {
#else
    void input(){
#endif
    for (int i = 0; i < 20; i++)
        for (int j = 0; j < 20; j++){
            puzzle.grid[i][j] = '.';
        }

    string str;
    for (int i = 0; i < puzzle_height; i++) {
#if READ_FROM_FILE
        ifs >> str;
#else
        cin>>str;
#endif
        for (int j = 0; j < puzzle_width; j++) {
            puzzle.grid[i][j] = str[j];
        }
    }
#if READ_FROM_FILE
    ifs >> num_pieces;
#else
    cin>>num_pieces;
#endif
    for (int k = 0; k < num_pieces; k++) {
#if READ_FROM_FILE
        ifs >> piece_h[k * 4] >> piece_w[k * 4];
#else
        cin>>piece_h[k*4]>>piece_w[k*4];
#endif
        for (int i = 0; i < piece_h[k * 4]; i++) {
#if READ_FROM_FILE
            ifs >> str;
#else
            cin>>str;
#endif
            for (int j = 0; j < piece_w[k * 4]; j++) {
                pieces[k * 4][i][j] = str[j];
            }
        }
        for (int i = 1; i < 4; i++) {
            piece_h[k * 4 + i] = piece_w[k * 4 + i - 1];
            piece_w[k * 4 + i] = piece_h[k * 4 + i - 1];
            rotate(k * 4 + i, k * 4 + i - 1);
        }
    }
}


bool can_append(int y, int x, int piece_idx) {
    if (y + piece_h[piece_idx] > puzzle_height || x + piece_w[piece_idx] > puzzle_width){
        return false;
    }
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#' && puzzle.grid[i][j] == '#'){
                return false;
            }
        }
    }
    return true;
}


void append_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '#';
            }
        }
    }
}


void remove_piece(int y, int x, int piece_idx) {
    for (int i = y; i < y + piece_h[piece_idx]; i++) {
        for (int j = x; j < x + piece_w[piece_idx]; j++) {
            if (pieces[piece_idx][i - y][j - x] == '#'){
                puzzle.grid[i][j] = '.';
            }
        }
    }
}
accuracy: 1
time_ms: 320
memory_kb: 8432
final_rank: 9

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 25

struct LOC{
	LOC(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Info{

	int num_tile;
	vector<LOC> V[4];
};

int H,W;
int N,POW[12];
int TABLE[SIZE][SIZE],ARRAY[10];
char table[SIZE][SIZE],work[SIZE][SIZE];
bool ans[1024],used[10];
vector<LOC> MAP;
Info info[10];


bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

void recursive(int index,int row,int col){

	if(row == H){

		int state = 0;
		for(int i = 0; i < index; i++){

			state += POW[ARRAY[i]];
		}
		ans[state] = true;
		return;
	}

	int next_row = row;
	int next_col = col+1;

	if(col == W-1){

		next_row = row+1;
		next_col = 0;
	}

	if(TABLE[row][col] != 0){

		recursive(index,next_row,next_col);
		return;
	}

	//TABLE[row][col] == 0 //空きマス


	for(int a = 0; a < N; a++){

		if(used[a])continue;

		int id = a;

		for(int i = 0; i < 4; i++){
			if(info[id].V[i].size() == 0)continue;
			bool FLG = true;
			for(int k = 0; k < info[id].num_tile; k++){

				if(!rangeCheck(row+info[id].V[i][k].row,col+info[id].V[i][k].col)){
					FLG = false;
					break;
				}
				if(TABLE[row+info[id].V[i][k].row][col+info[id].V[i][k].col] != 0){
					FLG = false;
					break;
				}
			}
			if(!FLG)continue;

			for(int k = 0; k < info[id].num_tile; k++){

				TABLE[row+info[id].V[i][k].row][col+info[id].V[i][k].col]++;
			}
			used[a] = true;
			ARRAY[index] = a;
			recursive(index+1,next_row,next_col);
			used[a] = false;
			for(int k = 0; k < info[id].num_tile; k++){

				TABLE[row+info[id].V[i][k].row][col+info[id].V[i][k].col]--;
			}
		}
	}
}

void func(){

	MAP.clear();

	for(int row = 0; row < H; row++){
		scanf("%s",table[row]);
		for(int col = 0; col < W; col++){
			if(table[row][col] == '.'){
				MAP.push_back(LOC(row,col));
			}
		}
	}

	scanf("%d",&N);

	for(int i = 0; i < N; i++){
		for(int k = 0; k < 4; k++){
			info[i].V[k].clear();
		}
	}

	int h,w;
	int base_row,base_col;

	for(int i = 0; i < N; i++){

		for(int row = 0; row < max(H,W); row++){
			for(int col = 0; col < max(H,W); col++){
				table[row][col] = '.';
			}
		}
		scanf("%d %d",&h,&w);
		for(int row = 0; row< h; row++){
			scanf("%s",work[row]);
			for(int col = 0; col < w; col++){
				if(work[row][col] == '#'){

					table[row][col] = '#';
				}
			}
		}

		for(int loop = 0; loop < 4; loop++){

			for(int row = 0; row < max(H,W); row++){
				for(int col = 0; col < max(H,W); col++){
					work[row][col] = '.';
				}
			}
			//90度回転
			for(int row = 0; row < max(H,W); row++){
				for(int col = 0; col < max(H,W); col++){
					work[col][W-1-row] = table[row][col];
				}
			}

			bool FLG = false;

			for(int row = 0; row < max(H,W); row++){
				for(int col = 0; col < max(H,W); col++){
					if(work[row][col] == '.')continue;

					if(!FLG){
						base_row = row;
						base_col = col;
						FLG = true;
					}
					info[i].V[loop].push_back(LOC(row-base_row,col-base_col));
				}
			}

			for(int row = 0; row < max(H,W); row++){
				for(int col = 0; col < max(H,W);col++){
					table[row][col] = work[row][col];
				}
			}
		}

		for(int a = 0; a < 3; a++){
			for(int b = a+1; b < 4; b++){
				bool FLG = true;
				for(int k = 0; k < info[i].V[a].size();k++){
					if(info[i].V[a][k].row != info[i].V[b][k].row || info[i].V[a][k].col != info[i].V[b][k].col){
						FLG = false;
						break;
					}
				}
				if(FLG){

					info[i].V[b].clear();
				}
			}
		}

		info[i].num_tile = info[i].V[0].size();
	}

	for(int state = 0; state < POW[N]; state++){

		ans[state] = false;
	}

	for(int i = 0; i < N; i++){
		used[i] = false;
	}
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			TABLE[row][col] = BIG_NUM;
		}
	}
	for(int i = 0; i < MAP.size(); i++){

		TABLE[MAP[i].row][MAP[i].col] = 0;
	}
	recursive(0,0,0);


	int num_query;
	scanf("%d",&num_query);

	int num,tmp;

	for(int i = 0; i < num_query; i++){

		scanf("%d",&num);
		int sum = 0;
		for(int k = 0; k < num; k++){

			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}

		if(ans[sum]){

			printf("YES\n");

		}else{

			printf("NO\n");
		}
	}
}


int main(){

	POW[0] = 1;
	for(int i = 1; i < 12; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 550
memory_kb: 3176
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;


using B = bitset<401>;
bool solve(){
    int h, w;
    cin >> h >> w;
    if(!h) return 0;
    B x;
    int cnt = 0;
    for (int i = 0; i < h; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < w; ++j) {
            if(s[j] == '#') {
                x.set(i*w+j);
                cnt++;
            }
        }
    }
    int n;
    cin >> n;
    vector<vector<B>> piece(n);
    vector<int> cnts(n);
    vector<int> ok(1 << n);
    for (int i = 0; i < n; ++i) {
        int hh, ww;
        cin >> hh >> ww;
        vector<string> v(hh);
        for (auto &&j : v) {
            cin >> j;
            for (auto &&k : j) {
                if(k == '#') cnts[i]++;
            }
        }
        for (int _ = 0; _ < 4; ++_) {
            for (int j = 0; j+hh <= h; ++j) {
                for (int k = 0; k+ww <= w; ++k) {
                    B y{};
                    for (int l = 0; l < hh; ++l) {
                        for (int m = 0; m < ww; ++m) {
                            if(v[l][m] == '#'){
                                y.set((j+l)*w+k+m);
                            }
                        }
                    }
                    piece[i].emplace_back(y);
                }
            }
            auto vv = vector<string>(ww, string(hh, ' '));
            for (int j = 0; j < hh; ++j) {
                for (int k = 0; k < ww; ++k) {
                    vv[ww-k-1][j] = v[j][k];
                }
            }
            swap(vv, v);
            swap(hh, ww);
        }
    }
    B MX{};
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            MX.set(i*w+j);
        }
    }
    int t;
    cin >> t;
    for (int i = 0; i < t; ++i) {
        int p;
        cin >> p;
        vector<int> v(p);
        for (auto &&j : v) scanf("%d", &j), j--;
        sort(v.begin(),v.end(), [&](int x, int y){ return cnts[x] > cnts[y]; });
        int dif = h*w-cnt;
        for (auto &&k : v) dif -= cnts[k];
        auto dfs = [&](int cur, B x, auto &&f) -> bool {
            if(cur == p) return 1;
            B xx = x;
            for (auto &&i : v) {
                for (auto &&j : piece[i]) {
                    if((x&j).none()){
                        xx |= j;
                    }
                }
            }
            if(xx != MX) return 0;
            for (auto &&j : piece[v[cur]]) {
                if((x&j).none()){
                    if(f(cur+1, x|j, f)) return 1;
                }
            }
            return 0;
        };
        if(!dif && dfs(0, x, dfs)) puts("YES");
        else puts("NO");
    }
    return 1;
}

int main() {
    while(solve()){}
    return 0;
}
accuracy: 1
time_ms: 3340
memory_kb: 3404
final_rank: 17

code_snippet: #include <ctime>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
const int inf = 1012345678;
vector<string> compress(vector<string> S) {
	int H = S.size(), W = S[0].size();
	int xl = inf, xr = -inf, yl = inf, yr = -inf;
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			if (S[i][j] == '#') {
				xl = min(xl, i);
				xr = max(xr, i);
				yl = min(yl, j);
				yr = max(yr, j);
			}
		}
	}
	vector<string> T(xr - xl + 1);
	for (int i = xl; i <= xr; ++i) {
		T[i - xl] = S[i].substr(yl, yr - yl + 1);
	}
	return T;
}
vector<string> rotate90(vector<string> S) {
	int H = S.size(), W = S[0].size();
	vector<string> T(W, string(H, '?'));
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			T[W - j - 1][i] = S[i][j];
		}
	}
	return T;
}
int main() {
	int H, W, N;
	while (cin >> H >> W, H) {
		vector<string> S(H);
		for (int i = 0; i < H; ++i) {
			cin >> S[i];
		}
		int all_sz = 0;
		vector<int> B(H);
		for (int i = 0; i < H; ++i) {
			for (int j = 0; j < W; ++j) {
				if (S[i][j] == '#') {
					B[i] |= 1 << j;
					++all_sz;
				}
			}
		}
		cin >> N;
		vector<int> R(N), C(N), SZ(N);
		vector<vector<int> > RX(N, vector<int>(4)), CX(N, vector<int>(4)), OY(N, vector<int>(4));
		vector<vector<vector<int> > > D(N, vector<vector<int> >(4));
		for (int i = 0; i < N; ++i) {
			cin >> R[i] >> C[i];
			vector<string> T(R[i]);
			for (int j = 0; j < R[i]; ++j) {
				cin >> T[j];
				for (int k = 0; k < C[i]; ++k) {
					if (T[j][k] == '#') ++SZ[i];
				}
			}
			T = compress(T);
			for (int j = 0; j < 4; ++j) {
				RX[i][j] = T.size();
				CX[i][j] = T[0].size();
				D[i][j].resize(RX[i][j]);
				for (int k = 0; k < RX[i][j]; ++k) {
					for (int l = 0; l < CX[i][j]; ++l) {
						if (T[k][l] == '#') {
							D[i][j][k] |= 1 << l;
						}
					}
				}
				for (int k = 0; k < CX[i][j]; ++k) {
					if (T[0][k] == '#') {
						OY[i][j] = k;
						break;
					}
				}
				T = rotate90(T);
			}
		}
		vector<int> cur = B;
		int u = clock();
		function<bool(int)> dfs = [&](int bit) {
			if (bit == 0) return true;
			if (clock() - u > CLOCKS_PER_SEC) return false;
			int lx = -1, ly = -1;
			for (int i = 0; i < H; ++i) {
				if (cur[i] != (1 << W) - 1) {
					for (int j = 0; j < W; ++j) {
						if (!((cur[i] >> j) & 1)) {
							lx = i, ly = j;
							break;
						}
					}
					break;
				}
			}
			for (int i = 0; i < N; ++i) {
				if (!((bit >> i) & 1)) continue;
				for (int j = 0; j < 4; ++j) {
					if (lx + RX[i][j] > H || ly + CX[i][j] - OY[i][j] > W || ly - OY[i][j] < 0) continue;
					bool ok = true;
					for (int k = 0; k < RX[i][j]; ++k) {
						if ((cur[lx + k] & (D[i][j][k] << (ly - OY[i][j]))) != 0) {
							ok = false;
						}
					}
					if (!ok) continue;
					for (int k = 0; k < RX[i][j]; ++k) {
						cur[lx + k] ^= D[i][j][k] << (ly - OY[i][j]);
					}
					bool res = dfs(bit - (1 << i));
					for (int k = 0; k < RX[i][j]; ++k) {
						cur[lx + k] ^= D[i][j][k] << (ly - OY[i][j]);
					}
					if (res) return true;
				}
			}
			return false;
		};
		int Q;
		cin >> Q;
		for (int i = 0; i < Q; ++i) {
			int K;
			cin >> K;
			vector<int> E(K);
			int bit = 0, sum_sz = all_sz;
			for (int j = 0; j < K; ++j) {
				cin >> E[j]; --E[j];
				bit |= 1 << E[j];
				sum_sz += SZ[E[j]];
			}
			if (sum_sz != H * W) {
				cout << "NO\n";
			}
			else {
				bool ans = dfs(bit);
				cout << (ans ? "YES\n" : "NO\n");
			}
		}
	}
	return 0;
}
accuracy: 1
time_ms: 2080
memory_kb: 3188
final_rank: 14

code_snippet: #include<iostream>
#include<bitset>
#include<vector>
#include<algorithm>
using namespace std;
int N,H,W,h[10],w[10];
string t[20];
bitset<400>R[10][4];
bool used[10];
int cnt[10];
vector<int>id;
bool dfs(const bitset<400>&F,int I,int rest)
{
	if(rest==0)return true;
	bool flag=true;
	int p;
	while(flag)
	{
		for(int j=0;j<W;j++)if(!F[I*W+j])
		{
			p=j;
			flag=false;
			break;
		}
		I+=flag;
	}
	bitset<400>test=F;
	for(int ii=0;ii<N;ii++)
	{
		int i=id[ii];
		if(used[i])continue;
		for(int r=0;r<4;r++)
		{
			for(int I=0;I<H;I++)
			{
				if(r%2==0&&I+h[i]>H||r%2==1&&I+w[i]>H)break;
				for(int J=0;J<W;J++)
				{
					if(r%2==0&&J+w[i]>W||r%2==1&&J+h[i]>W)break;
					if(!(F&(R[i][r]<<I*W+J)).any())test|=R[i][r]<<I*W+J;
				}
			}
		}
	}
	if(test.count()!=H*W)return false;
	for(int ii=0;ii<N;ii++)
	{
		int i=id[ii];
		if(used[i])continue;
		used[i]=true;
		for(int r=0;r<4;r++)
		{
			if(r%2==0&&I+h[i]>H||r%2==1&&I+w[i]>H)continue;
			for(int J=0;J<=p;J++)
			{
				if(r%2==0&&J+w[i]>W||r%2==1&&J+h[i]>W)break;
				if(!R[i][r][p-J])continue;
				if((F&(R[i][r]<<I*W+J)).any())continue;
				if(dfs(F|(R[i][r]<<I*W+J),I,rest-cnt[i]))return true;
			}
		}
		used[i]=false;
	}
	return false;
}
main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	while(cin>>H>>W,H)
	{
		bitset<400>F;
		for(int i=0;i<H;i++)
		{
			string s;cin>>s;
			for(int j=0;j<W;j++)
			{
				if(s[j]=='#')F[i*W+j]=1;
			}
		}
		cin>>N;
		id.clear();
		for(int i=0;i<N;i++)
		{
			id.push_back(i);
			cin>>h[i]>>w[i];
			for(int r=0;r<4;r++)R[i][r].reset();
			cnt[i]=0;
			for(int j=0;j<h[i];j++)cin>>t[j];
			for(int I=0;I<h[i];I++)for(int J=0;J<w[i];J++)if(t[I][J]=='#')
			{
				cnt[i]+=1;
				R[i][0][I*W+J]=1;
				R[i][1][J*W+(h[i]-I-1)]=1;
				R[i][2][(h[i]-I-1)*W+(w[i]-J-1)]=1;
				R[i][3][(w[i]-J-1)*W+I]=1;
			}
		}
		sort(id.begin(),id.end(),[](int a,int b){return cnt[a]>cnt[b];});
		int p;cin>>p;
		int T=H*W-F.count();
		for(;p--;)
		{
			int k;cin>>k;
			for(int i=0;i<N;i++)used[i]=true;
			int left=T;
			for(;k--;)
			{
				int a;cin>>a;a--;
				used[a]=false;
				left-=cnt[a];
			}
			cout<<(left==0&&dfs(F,0,T)?"YES":"NO")<<endl;
		}
	}
}
accuracy: 1
time_ms: 4020
memory_kb: 3116
final_rank: 18

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int INF = 1 << 28;

class Piece
{
private:
	int h, w;
	char g[20][20];
	vector<int> bit;

public:
	Piece() { };

	bool readFromStdin(bool cutflag = true)
	{
		cin >> h >> w;
		if (h == 0 &&  w == 0)
			return false;

		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
			{
				char c;
				cin >> c;
				g[y][x] = c;
			}
		}

		if (cutflag)
			reduce();

		makeBitVector();
		return true;
	}

	void reduce()
	{
		int ly, lx, hy, hx;
		int x, y;
		for (x = 0; x < w; ++x)
		{
			for (y = 0; y < h; ++y)
			{
				if (g[y][x] == '#')
					break;
			}			

			if (y < h)
				break;
		}

		lx = x;
		for (x = w - 1; x >= 0; --x)
		{
			for (y = 0; y < h; ++y)
			{
				if (g[y][x] == '#')
					break;
			}			

			if (y < h)
				break;
		}

		hx = x;
		for (y = 0; y < h; ++y)
		{
			for (x = 0; x < w; ++x)
			{
				if (g[y][x] == '#')
					break;
			}			

			if (x < w)
				break;
		}

		ly = y;
		for (y = h - 1; y >= 0; --y)
		{
			for (x = 0; x < w; ++x)
			{
				if (g[y][x] == '#')
					break;
			}			

			if (x < w)
				break;
		}

		hy = y;

		h = hy - ly + 1;
		w = hx - lx + 1;
		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
				g[y][x] = g[ly + y][lx + x];
		}
	}

	void makeBitVector()
	{
		bit.clear();
		for (int y = 0; y < h; ++y)
		{
			int b = 0;
			for (int x = 0; x < w; ++x)
				b |= ((g[y][x] == '#') ? 1 : 0) << x;

			bit.push_back(b);
		}
	}

	Piece rotate() const
	{
		Piece p;
		p.h = w;
		p.w = h;

		for (int y = 0; y < p.h; ++y)
		{
			for (int x = 0; x < p.w; ++x)
				p.g[y][x] = g[h - 1 - x][y];
		}

		p.makeBitVector();
		return p;
	}

	bool ok(const Piece &p, int by, int bx) const
	{
		if (by < 0 || by + p.h > h)
			return false;

		if (bx < 0 || bx + p.w > w)
			return false;

		for (int y = 0; y < p.h; ++y)
		{
			if (bit[by + y] & (p.bit[y] << bx))
				return false;
		}

		return true;
	}

	void bury(const Piece &p, int by, int bx)
	{
		for (int y = 0; y < p.h; ++y)
			bit[by + y] |= p.bit[y] << bx;
	}

	void erase(const Piece &p, int by, int bx)
	{
		for (int y = 0; y < p.h; ++y)
			bit[by + y] &= ~(p.bit[y] << bx);
	}

	int getH() const { return h; }
	int getW() const { return w; }
	int getSize() const { return h * w; }
	bool getDot(int y, int j) const { return (bit[y] >> j) & 1; }

	int getCount() const
	{
		int res = 0;
		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
				res += (g[y][x] == '#') ? 1 : 0;
		}

		return res;
	}

	void show() const
	{
		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
				cout << g[y][x];

			cout << endl;
		}
	}
};

const int MAX_N = 10;
int H, W;
Piece base;
int n;
Piece piece[MAX_N][4];
int t[MAX_N];

bool
rec(int s1, int e1)
{
	if (s1 == e1)
		return true;

	{
		Piece b = base;
		for (int by = 0; by < H; ++by)
		{
			for (int bx = 0; bx < W; ++bx)
			{
				if (!b.getDot(by, bx))
				{
					for (int i = s1; i != e1; ++i)
					{
						for (int a = 0; a < 4; ++a)
						{
							const Piece &p = piece[t[i]][a];
							int h = p.getH();
							int w = p.getW();
							for (int y = max(0, by - h + 1); y <= by && y + h <= H; ++y)
							{
								for (int x = max(0, bx - w + 1); x <= bx && x + w <= W; ++x)
								{
									if (base.ok(p, y, x))
										b.bury(p, y, x);
								}
							}
						}
					}
				}

				if (!b.getDot(by, bx))
					return false;
			}
		}
	}

	for (int a = 0; a < 4; ++a)
	{
		const Piece &p = piece[t[s1]][a];
		int h = p.getH();
		int w = p.getW();
		for (int y = 0; y + h <= H; ++y)
		{
			for (int x = 0; x + w <= W; ++x)
			{
				if (base.ok(p, y, x))
				{
					base.bury(p, y, x);
					bool res = rec(s1 + 1, e1);
					base.erase(p, y, x);
					if (res)
						return true;
				}
			}
		}
	}

	return false;
}

int
main(int argc, char **argv)
{
	int k;

	while (base.readFromStdin(false))
	{
		H = base.getH();
		W = base.getW();
		cin >> n;
		for (int s = 0; s < n; ++s)
		{
			piece[s][0].readFromStdin();
			for (int a = 1; a < 4; ++a)
				piece[s][a] = piece[s][a - 1].rotate();
		}

		int p;
		cin >> p;
		while(p--)
		{
			{
				cin >> k;
				vector<pair<int,int> > tmp(k);
				for (int i = 0; i < k; ++i)
				{
					cin >> tmp[i].second;
					tmp[i].second--;
					tmp[i].first = -piece[tmp[i].second][0].getSize();
				}

				sort(tmp.begin(), tmp.end());
				for (int i = 0; i < k; ++i)
					t[i] = tmp[i].second;
			}

			int sum = 0;
			for (int i = 0; i < k; ++i)
				sum += piece[t[i]][0].getCount();

			if (sum == base.getSize() - base.getCount() && rec(0, k))
				cout << "YES" << endl;
			else
				cout << "NO" << endl;
		}
	}

	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3180
final_rank: 2

code_snippet: #include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
int H, W, n, h[40], w[40], sz[40];
int m, no[10];
char in[20][21], pc[40][20][21];
bool v[20][20], u[20][20];

bool cmp(int a, int b){
	return sz[a] > sz[b];
}
bool rec(int c){
	if(c == m) return 1;
	memset(u, 0, sizeof(u));
	rep(i, H) rep(j, W) if(in[i][j] == '.' && !u[i][j]){
		for(int k = c; k < m; k++) rep(t, 4){
			int p = no[k] + t * n;
			for(int y = max(0, i - h[p] + 1); y <= i && y + h[p] <= H; y++)
			for(int x = max(0, j - w[p] + 1); x <= j && x + w[p] <= W; x++){
				rep(a, h[p]) rep(b, w[p]){
					if(pc[p][a][b] == '#' && in[y + a][x + b] == '#') goto FAIL;
				}
				rep(a, h[p]) rep(b, w[p]){
					if(pc[p][a][b] == '#') u[y + a][x + b] = 1;
				}
				FAIL:;
			}
		}
		if(!u[i][j]) return 0;
	}
	rep(t, 4){
		int p = no[c] + t * n;
		for(int y = 0; y + h[p] <= H; y++)
		for(int x = 0; x + w[p] <= W; x++){
			bool ok = 1;
			rep(a, h[p]) rep(b, w[p]) if(in[y + a][x + b] == '#' && pc[p][a][b] == '#') ok = 0;
			if(ok){
				rep(a, h[p]) rep(b, w[p]) if(pc[p][a][b] == '#') in[y + a][x + b] = '#';
				bool res = rec(c + 1);
				rep(a, h[p]) rep(b, w[p]) if(pc[p][a][b] == '#') in[y + a][x + b] = '.';
				if(res) return 1;
			}
		}
	}
	return 0;
}

int main()
{while(cin >> H >> W, H){int sp = 0;rep(i, H){cin >> in[i];rep(j, W) if(in[i][j] == '.') sp++;}cin >> n;
		rep(i, n){cin >> h[i] >> w[i];sz[i] = 0;rep(j, h[i]){	cin >> pc[i][j];
		rep(k, w[i]) if(pc[i][j][k] == '#') sz[i]++;}
			int s = i;rep(j, 3){
				int t = s + n;

				h[t] = w[s];
				w[t] = h[s];
				sz[t] = sz[s];

				rep(y, h[s]) rep(x, w[s])
					pc[t][x][h[s] - y - 1] = pc[s][y][x];
				s = t;
			}
		}
		int q;
		cin >> q;
		while(q--){
			cin >> m;
			int sum = 0;
			rep(i, m) cin >> no[i], sum += sz[--no[i]];
			sort(no, no + m, cmp);

			memset(v, 0, sizeof(v));
			cout << (sum == sp && rec(0) ? "YES" : "NO") << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 3152
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
#include <set>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define all(n) n.begin(),n.end()
typedef long long ll;

int bx[20];
int xbit[10][4][20];
int H[10][4],W[10][4];
int pzlCnt[10];
int num[10];
int h,w,P;
int v[10];

int generate(int _bx[20],deque<string> t,char del,int &_H,int &_W){
	rep(i,20) _bx[i] = 0;
	while(count(all(t[0]),del) == t[0].size()) t.pop_front();
	while(count(all(t[t.size()-1]),del) == t[t.size()-1].size()) t.pop_back();
	while(1){
		bool f = true;
		rep(i,t.size()) f &= t[i][0] == del;
		if(f) rep(i,t.size()) t[i] = t[i].substr(1); else break;
	}
	while(1){
		bool f = true;
		rep(i,t.size()) f &= t[i][t[i].size()-1] == del;
		if(f) rep(i,t.size()) t[i] = t[i].erase(t[i].size()-1); else break;
	}
	int H = t.size() , W = t[0].length();
	
	rep(i,H)rep(j,W) _bx[i] |= ( (t[i][j]=='#') << j);
	_W = W , _H = H;
}

string genString(char c,int l){
	string ans;
	rep(i,l)ans += c;
	return ans;
}

void fix(deque<string> &t){
	int mxsz = max(t.size(),t[0].size());
	rep(i,t.size()) while(t[i].size() < mxsz) t[i] += '.';
	while(t.size() < mxsz) t.push_back(genString('.',mxsz));
}
void rotate(deque<string> &t){
	rep(i,t.size()) rep(j,i) swap(t[i][j],t[j][i]);
	rep(i,t.size()) reverse(all(t[i]));
}


bool isok(int ax[20],int tx[20],int x,int y){
	rep(i,20) if(ax[i+y] & (tx[i] << x) )return false;
	return true;
}
void add(int a[20],int b[20],int x,int y){rep(i,20) a[i+y] |= (b[i]<<x);}
void sub(int a[20],int b[20],int x,int y){rep(i,20) a[i+y] &= ~(b[i]<<x);}

struct NODE{
	int v[20];
	NODE(int a[20]){rep(i,20)v[i] = a[i];}
};

bool operator < (const NODE &a, const NODE& b){
	rep(i,20)if(a.v[i] != b.v[i]) return a.v[i] < b.v[i];
	return false;
}

set<NODE> memo[10];

int dfs(int k , int cx[20]){
	if(k == P)return true;
	
	NODE key(cx);
	if(memo[k].find(key) != memo[k].end())return false;
	else memo[k].insert(key);
	
	int cur = v[k];
	
	int pre[20]={0};
	for(int f=k;f<P;f++){
		int c = v[f];
		rep(d,4){
			rep(i,h-H[c][d]+1){
				rep(j,w-W[c][d]+1){
					if( isok(cx,xbit[c][d],j,i) ){
						add(pre,xbit[c][d],j,i);
					}
				}
			}
		}
	}
	rep(i,h){
		if( pre[i] != ((~cx[i]) & ((1<<w)-1)) ) return false;
	}
	
	rep(d,4){
		rep(i,h-H[cur][d]+1){
			rep(j,w-W[cur][d]+1){
				if( isok(cx,xbit[cur][d],j,i) ){
					add(cx,xbit[cur][d],j,i);
					if(dfs(k+1,cx)) return true;
					sub(cx,xbit[cur][d],j,i);
				}
			}
		}
	}
	
	return false;
}

int _2dCount(deque<string> &t,char c){
	int ans = 0;
	rep(i,t.size())rep(j,t[i].size()) ans += t[i][j] == c;
	return ans;
}

int main(){
	string t;
	deque<string> tmp;
	while(cin >> h >> w && h || w){
		rep(i,10)num[i] = i;
		
		tmp.clear(); rep(i,h)cin >> t , tmp.push_back(t);
		
		generate(bx,tmp,'-',h,w);
		int allCnt = _2dCount(tmp,'.');
		int N; cin >> N;
		rep(k,N){
			tmp.clear();
			int th,tw; cin >> th >> tw;
			rep(i,th)cin >> t , tmp.push_back(t);
			pzlCnt[k] = _2dCount(tmp,'#');
			fix(tmp);
			rep(d,4){
				generate(xbit[k][d] , tmp , '.' , H[k][d] , W[k][d]);
				rotate(tmp);
			}
		}
		int Q; cin >> Q;
		rep(x,Q){
			rep(i,10)memo[i].clear();
			int qCnt = 0;
			int tmpField[20];
			rep(i,20)tmpField[i] = bx[i];
			cin >> P;
			rep(j,P) cin >> v[j] , v[j] = find(num,num+10,v[j]-1)-num , qCnt += pzlCnt[v[j]];
			if(qCnt == allCnt && dfs(0,tmpField)){
				cout << "YES" << endl;
			}else{
				cout << "NO" << endl;
			}
		}
	}
}
accuracy: 1
time_ms: 330
memory_kb: 3192
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define BIT(x) (1 << (x))

struct Piece {
	int h, w;
	vector<int> v;
};

int H, W;
int n;
int board[20];
Piece p[10][4];

void generate(vector<vector<int> > v, Piece p[])
{
	for (int i = 0; i < 4; i++){
		int bx = 20, by = 20, ex = -1, ey = -1;
		for (int j = 0; j < 20; j++){
			for (int k = 0; k < 20; k++){
				if (v[j][k]){
					bx = min(bx, j);
					by = min(by, k);
					ex = max(ex, j);
					ey = max(ey, k);
				}
			}
		}
		p[i].h = ex - bx + 1;
		p[i].w = ey - by + 1;
		p[i].v.assign(p[i].h, 0);
		for (int j = 0; j < p[i].h; j++){
			for (int k = 0; k < p[i].w; k++){
				if (v[bx + j][by + k]){
					p[i].v[j] |= BIT(k);
				}
			}
		}
		
		vector<vector<int> > nx(20, vector<int>(20));
		for (int i = 0; i < 20; i++){
			for (int j = 0; j < 20; j++){
				nx[i][j] = v[j][19 - i];
			}
		}
		v = nx;
	}
}

vector<int> ch;
vector<int> used;
bool check()
{
	int sum = 0;
	for (int i = 0; i < 20; i++){
		sum += __builtin_popcount(~board[i]);
	}
	for (int i = 0; i < ch.size(); i++){
		for (int j = 0; j < p[ch[i]][0].v.size(); j++){
			sum -= __builtin_popcount(p[ch[i]][0].v[j]);
		}
	}
	return sum == 0;
}

bool can(int x, int y, Piece &pi)
{
	for (int i = 0; i < pi.h; i++){
		if (board[x + i] & (pi.v[i] << y)){
			return false;
		}
	}
	return true;
}

bool act(int x, int y, Piece &pi)
{
	for (int i = 0; i < pi.h; i++){
		board[x + i] ^= pi.v[i] << y;
	}
}

bool ng()
{
	int b[20] = {};
	for (int i = 0; i < 20; i++) b[i] = board[i];
	for (int i = 0; i < ch.size(); i++){
		if (used[i]) continue;
		for (int a = 0; a < 4; a++){
			Piece &pi = p[ch[i]][a];
			for (int j = 0; j + pi.h <= H; j++){
				for (int k = 0; k + pi.w <= W; k++){
					if (can(j, k, pi)){
						for (int l = 0; l < pi.h; l++){
							b[j + l] |= pi.v[l] << k;
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < 20; i++){
		if (b[i] != -1) return true;
	}
	return false;
}

bool dfs(int cur)
{
	if (cur == ch.size()) return true;
	if (ng()) return false;
	
	for (int a = 0; a < 4; a++){
		Piece &pi = p[ch[cur]][a];
		for (int i = 0; i + pi.h <= H; i++){
			for (int j = 0; j + pi.w <= W; j++){
				if (can(i, j, pi)){
					act(i, j, pi);
					used[cur] = true;
					bool f = dfs(cur + 1);
					act(i, j, pi);
					used[cur] = false;
					if (f) return true;
				}
			}
		}
	}
	return false;
}

int main()
{
	while (scanf("%d %d", &H, &W), H){
		memset(board, -1, sizeof(board));
		
		for (int i = 0; i < H; i++){
			string str;
			cin >> str;
			for (int j = 0; j < W; j++){
				if (str[j] == '.') board[i] ^= BIT(j);
			}
		}
		
		scanf("%d", &n);
		for (int i = 0; i < n; i++){
			int h, w;
			scanf("%d %d", &h, &w);
			vector<vector<int> > buf(20, vector<int>(20));
			for (int j = 0; j < h; j++){
				for (int k = 0; k < w; k++){
					char c;
					cin >> c;
					if (c == '#') buf[j][k] = 1;
				}
			}
			generate(buf, p[i]);
		}
		
		int m;
		scanf("%d", &m);
		for (int i = 0; i < m; i++){
			int k;
			scanf("%d", &k);
			ch.resize(k);
			used.assign(k, 0);
			for (int j = 0; j < k; j++){
				scanf("%d", &ch[j]);
				ch[j]--;
			}
			puts(check() && dfs(0) ? "YES" : "NO");
		}
	}
}
accuracy: 1
time_ms: 530
memory_kb: 1252
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <bitset>
#include <algorithm>
using namespace std;

vector<string> puzzle_flame;
int puzzle_size;
int puzzle_w;
int puzzle_h;
int piece_num;

struct piece {
	vector<vector<string> > p;
	int size;
	vector<int> sharp_x;
	vector<int> sharp_y;
	bitset<4> same_flg;
	piece() {}
	piece(vector<string> v) {
// make rotate piece {{{
		vector<string> tmp;

		p.push_back(v);

		for(int i = 0; i < v[0].size(); i++) {
			string s = "";
			for(int j = 0; j < v.size(); j++) {
				s += v[j][v[0].size() - 1 - i];
			}
			tmp.push_back(s);
		}
		p.push_back(tmp);

		tmp.clear();
		for(int i = 0; i < v.size(); i++) {
			string s = "";
			for(int j = 0; j < v[i].size(); j++) {
				s += v[v.size() - 1 - i][v[0].size() - 1 - j];
			}
			tmp.push_back(s);
		}
		p.push_back(tmp);

		tmp.clear();
		for(int i = 0; i < v[0].size(); i++) {
			string s = "";
			for(int j = 0; j < v.size(); j++) {
				s += v[v.size() - 1 - j][i];
			}
			tmp.push_back(s);
		}
		p.push_back(tmp);
// }}}
// init size {{{
		size = 0;
		for(int i = 0; i < v.size(); i++) {
			for(int j = 0; j < v[i].size(); j++) {
				size += v[i][j] == '#';
			}
		}
// }}}
// make sharp_x,y {{{
		for(int i = 0; i < p.size(); i++) {
			for(int j = 0; j < p[i].size(); j++) {
				for(int k = 0; k < p[i][j].size(); k++) {
					if(p[i][j][k] == '#') {
						sharp_y.push_back(j);
						sharp_x.push_back(k);
						goto exit_mk_sharp;
					}
				}
			}
exit_mk_sharp:;
		}
// }}}
		for(int i = 0; i < p.size(); i++) {
			same_flg[i] = false;
			for(int j = 0; j < i; j++) {
				if(p[i].size() == p[j].size()) {
					bool flg = true;
					for(int k = 0; k < p[i].size(); k++) {
						for(int l = 0; l < p[i][k].size(); l++) {
							if(p[i][k][l] != p[j][k][l]) {
								flg = false;
							}
						}
					}
					if(flg)
						same_flg[i] = true;
				}
			}
		}
	}
};

vector<piece> usable_pieces;

bitset<64> interference[40][40][64];
const int margin = 32;
// piece a, b, bias Y b - a, bias X b - a
void set_interference() { // {{{
	for(int i = 0; i < usable_pieces.size()*4; i++) {
		const vector<string> a = usable_pieces[i >> 2].p[i & 0x3];
		for(int j = 0; j < usable_pieces.size()*4; j++) {
			const vector<string> b = usable_pieces[j >> 2].p[j & 0x3];

		//	cout << i << "," << j << endl;
		//	cout << (i >> 2) << "," << (i & 0x3) << " " << (j >> 2) << "," << (j & 0x3) << endl;

			if((i >> 2) == (j >> 2)) {
				for(int bias_i = 0; bias_i < 64; bias_i++) {
					for(int bias_j = 0; bias_j < 64; bias_j++) {
						interference[i][j][bias_i][bias_j] = false;
					}
				}
				continue;
			}

			for(int bias_i = -25; bias_i <= 25; bias_i++) {
				for(int bias_j = -25; bias_j <= 25; bias_j++) {
					bool f = true;
					for(int i_ = max(0, bias_i); i_ < min((int)a.size(), (int)b.size() + bias_i); i_++) {
						for(int j_ = max(0, bias_j); j_ < min((int)a[0].size(), (int)b[0].size() + bias_j); j_++) {
							if((a[i_][j_] == '#') && (b[i_ - bias_i][j_ - bias_j] == '#'))
								f = false;
						}
					}
					if(f)
						interference[i][j][margin + bias_i].set(margin + bias_j);
					else {
						interference[i][j][margin + bias_i].reset(margin + bias_j);
					}
				}
			}
		}
	}
// }}}
}


bitset<20> put[40][20];
void set_put() { // {{{
	for(int i = 0; i < usable_pieces.size()*4; i++) {
		const vector<string> a = usable_pieces[i >> 2].p[i & 0x3];
		for(int j = 0; j < puzzle_h; j++) {
			for(int k = 0; k < puzzle_w; k++) {
				if(j + a.size() > puzzle_h || k + a[0].size() > puzzle_w) {
					break;
				}

				bool f = true;
				for(int j_ = 0; j_ < a.size(); j_++) {
					for(int k_ = 0; k_ < a[j_].size(); k_++) {
						if(puzzle_flame[j+j_][k+k_] == '#' && a[j_][k_] == '#')
							f = false;
					}
				}

				if(f)
					put[i][j].set(k);
				else
					put[i][j].reset(k);
			}
		}
	}
	//cout << endl;
// }}}
}

int piece_list;
struct position {
	int x, y;
	int n;
	position(int x_, int y_, int n_) {
		x = x_;
		y = y_;
		n = n_;
	}
};
vector<position> use;
int use_flgs;

bool solve(int y, int x) {
	/*
	cout << endl;
	for(int i = 0; i < puzzle_h; i++) {
		cout << puzzle_flame[i] << endl;
	} cout << endl;
	for(int i = 0; i < 10; i++)
		cout << (((piece_list^use_flgs) & (1 << i)) ? '1' : '0');
	cout << endl;
	for(int i = 0; i < puzzle_h; i++) {
		for(int j = 0; j < puzzle_w; j++) {
			if(puzzle_flame[i][j] == '*')
				puzzle_flame[i][j] = '#';
		}
	}
	// */
	if(!(piece_list ^ use_flgs))
		return true;
	for(int i = 0; i < puzzle_h; i++) {
		for(int j = 0; j < puzzle_w; j++) {
			if(puzzle_flame[i][j] == '.') {
			//	cout << "i,j:" << i << "," << j << endl;
				for(int k = 0; k < piece_num; k++) {
					if((piece_list ^ use_flgs) & (1 << k)) {
						for(int l = 0; l < 4; l++) {
							if(usable_pieces[k].same_flg[l]) {
								continue;
							}
							int X, Y;
							Y = i - usable_pieces[k].sharp_y[l];
							X = j - usable_pieces[k].sharp_x[l];
				//			cout << X << "," << Y << "," << k << endl;
							if(Y >= 0 && X >= 0 && put[(k << 2) + l][Y][X]) {
								bool call_flg = true;
								for(int m = 0; m < use.size(); m++) {
									call_flg &= interference[(k<<2)+l][use[m].n][margin + use[m].y - Y][margin + use[m].x - X];
								//	cout << use[m].y << "," << use[m].x << "," << use[m].n << endl;
								}
								if(call_flg) {
									int next_x, next_y;
									next_x = (j + 1) % puzzle_w;
									next_y = i + (j + 1) / puzzle_w;

									for(int i_ = 0; i_ < usable_pieces[k].p[l].size(); i_++) {
										for(int j_ = 0; j_ < usable_pieces[k].p[l][i_].size(); j_++) {
											if(usable_pieces[k].p[l][i_][j_] == '#') {
												/*
												if(puzzle_flame[Y + i_][X + j_] == '#')
													cout << "fail" << endl;
												// */
												puzzle_flame[Y + i_][X + j_] = '#';
											}
										}
									}

									use.push_back(position(X,Y,(k << 2)+l));
									use_flgs |= 1 << k;

									bool solve_res;
									solve_res = solve(next_y, next_x);

									for(int i_ = 0; i_ < usable_pieces[k].p[l].size(); i_++) {
										for(int j_ = 0; j_ < usable_pieces[k].p[l][i_].size(); j_++) {
											if(usable_pieces[k].p[l][i_][j_] == '#') {
												puzzle_flame[Y + i_][X + j_] = '.';
											}
										}
									}
									use.pop_back();
									use_flgs &= ~(1 << k);

									if(solve_res)
										return true;
								}
							}
						}
					}
				}

				return false;
			}
		}
	}
	return false;
}

void init_global_val() {
	puzzle_flame.clear();
	puzzle_size = 0;
	puzzle_w = 0;
	puzzle_h = 0;
	piece_num = 0;
	usable_pieces.clear();
	for(int i = 0; i < 40; i++) {
		for(int j = 0; j < 40; j++) {
			for(int k = 0; k < 64; k++) {
				for(int l = 0; l < 64; l++) {
					interference[i][j][k].set(l);
				}
			}
		}
	}
	piece_list = 0;
	use.clear();
	use_flgs = 0;
	for(int i = 0; i < 40; i++) {
		for(int j = 0; j < 20; j++) {
			for(int k = 0; k < 20; k++) {
				put[i][j].reset(k);
			}
		}
	}
}

void solve_init() {
	piece_list = 0;
	use_flgs = 0;
	use.clear();
}

int main() {
	init_global_val();
	while(cin >> puzzle_h >> puzzle_w, puzzle_h || puzzle_w) {
// input puzzle {{{
		for(int i = 0; i < puzzle_h; i++) {
			string s;
			cin >> s;
			puzzle_flame.push_back(s);
		}
		cin >> piece_num;
		for(int i = 0; i < piece_num; i++) {
			int h, w;
			cin >> h >> w;
			vector<string> v;
			for(int j = 0; j < h; j++) {
				string s;
				cin >> s;
				v.push_back(s);
			}
			usable_pieces.push_back(piece(v));
		}
// }}}
// prepaire {{{
		puzzle_size = 0;
		for(int i = 0; i < puzzle_flame.size(); i++) {
			for(int j = 0; j < puzzle_flame[i].size(); j++) {
				puzzle_size += (puzzle_flame[i][j] == '.');
			}
		}

		//cout << puzzle_size << endl;

		set_interference();
		set_put();

		/*
		for(int i = 0; i < 4*usable_pieces.size(); i++) {
			cout << (i >> 2) << ":" << (i & 0x3) << endl;
			for(int j = 0; j < puzzle_h; j++) {
				for(int k = 0; k < puzzle_w; k++) {
					cout << (put[i][j][k] ? '.' : '@');
				}
				cout << endl;
			}
			cout << endl;
		}
		// */
// }}}
// query {{{
		int query_num;
		cin >> query_num;
		for(int q = 0; q < query_num; q++) {
			int n;
			cin >> n;
			solve_init();

			int sz = 0;
			for(int i = 0; i < n; i++) {
				int k;
				cin >> k;
				piece_list ^= (1 << (k - 1));
				sz += usable_pieces[k-1].size;
			}

			/*
			if(puzzle_size != sz)
				cout << "size error:";
			// */
			if(puzzle_size == sz && solve(0,0))
				cout << "YES" << endl;
			else
				cout << "NO" << endl;
		}
// }}}
		init_global_val();
	}
}
accuracy: 1
time_ms: 2530
memory_kb: 2084
final_rank: 15

code_snippet: #include<stdio.h>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
char str[22][22];
int has[12];
char p[12][22][22];
int bit[12][4][22];
int h[12];
int w[12];
int r;
int com[12];
vector<int> now;
int H,W;

//set<vector<int> >S;
int solve(int a){
	if(a==r)return 1;
//	if(S.count(now))return 0;
//	S.insert(now);
	int tmp[22];
	for(int i=0;i<H;i++)tmp[i]=now[i];
	for(int i=a;i<r;i++){
		int v=com[i];
		for(int j=0;j<=H-h[v];j++)for(int k=0;k<=W-w[v];k++){
			bool ok=true;
			for(int l=0;l<h[v];l++)if((bit[v][0][l]<<k)&now[j+l]){ok=false;break;}
			if(ok){
				for(int l=0;l<h[v];l++)tmp[j+l]|=(bit[v][0][l]<<k);
			}
		}
		for(int j=0;j<=H-h[v];j++)for(int k=0;k<=W-w[v];k++){
			bool ok=true;
			for(int l=0;l<h[v];l++)if((bit[v][2][l]<<k)&now[j+l]){ok=false;break;}
			if(ok){
				for(int l=0;l<h[v];l++)tmp[j+l]|=(bit[v][2][l]<<k);
			}
		}
		for(int j=0;j<=H-w[v];j++)for(int k=0;k<=W-h[v];k++){
			bool ok=true;
			for(int l=0;l<w[v];l++)if((bit[v][1][l]<<k)&now[j+l]){ok=false;break;}
			if(ok){
				for(int l=0;l<w[v];l++)tmp[j+l]|=(bit[v][1][l]<<k);
			}
		}
		for(int j=0;j<=H-w[v];j++)for(int k=0;k<=W-h[v];k++){
			bool ok=true;
			for(int l=0;l<w[v];l++)if((bit[v][3][l]<<k)&now[j+l]){ok=false;break;}
			if(ok){
				for(int l=0;l<w[v];l++)tmp[j+l]|=(bit[v][3][l]<<k);
			}
		}
	}
	for(int i=0;i<H;i++)for(int j=0;j<W;j++)if(!(tmp[i]&(1<<j)))return 0;
	int f=com[a];
	for(int i=0;i<=H-h[f];i++){
		for(int j=0;j<=W-w[f];j++){
			bool ok=true;
			for(int k=0;k<h[f];k++)if((bit[f][0][k]<<j)&now[i+k]){ok=false;break;}
			if(ok){
				for(int k=0;k<h[f];k++)now[i+k]^=(bit[f][0][k]<<j);
				if(solve(a+1))return 1;
				for(int k=0;k<h[f];k++)now[i+k]^=(bit[f][0][k]<<j);
			}
		}
	}
	for(int i=0;i<=H-h[f];i++){
		for(int j=0;j<=W-w[f];j++){
			bool ok=true;
			for(int k=0;k<h[f];k++)if((bit[f][2][k]<<j)&now[i+k]){ok=false;break;}
			if(ok){
				for(int k=0;k<h[f];k++)now[i+k]^=(bit[f][2][k]<<j);
				if(solve(a+1))return 1;
				for(int k=0;k<h[f];k++)now[i+k]^=(bit[f][2][k]<<j);
			}
		}
	}
	for(int i=0;i<=H-w[f];i++){
		for(int j=0;j<=W-h[f];j++){
			bool ok=true;
			for(int k=0;k<w[f];k++)if((bit[f][1][k]<<j)&now[i+k]){ok=false;break;}
			if(ok){
				for(int k=0;k<w[f];k++)now[i+k]^=(bit[f][1][k]<<j);
				if(solve(a+1))return 1;
				for(int k=0;k<w[f];k++)now[i+k]^=(bit[f][1][k]<<j);
			}
		}
	}
	for(int i=0;i<=H-w[f];i++){
		for(int j=0;j<=W-h[f];j++){
			bool ok=true;
			for(int k=0;k<w[f];k++)if((bit[f][3][k]<<j)&now[i+k]){ok=false;break;}
			if(ok){
				for(int k=0;k<w[f];k++)now[i+k]^=(bit[f][3][k]<<j);
				if(solve(a+1))return 1;
				for(int k=0;k<w[f];k++)now[i+k]^=(bit[f][3][k]<<j);
			}
		}
	}
	return 0;
}
int sts[12];
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a){
		H=a;W=b;
		for(int i=0;i<a;i++)scanf("%s",str[i]);
		int cnt=0;
		now=vector<int>(a);
		for(int i=0;i<a;i++)now[i]=0;
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)if(str[i][j]=='#')now[i]+=(1<<j);
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)if(str[i][j]=='.')cnt++;
		int n;scanf("%d",&n);
		for(int i=0;i<n;i++)for(int j=0;j<4;j++)for(int k=0;k<22;k++)
			bit[i][j][k]=0;
		for(int i=0;i<n;i++){
			has[i]=0;
			scanf("%d%d",h+i,w+i);
			sts[i]=max((H-h[i]+1)*(W-w[i]+1),(H-w[i]+1)*(W-h[i]+1));
			for(int j=0;j<h[i];j++)scanf("%s",p[i][j]);
			for(int j=0;j<h[i];j++){
				for(int k=0;k<w[i];k++){
					if(p[i][j][k]=='#'){
						has[i]++;
						bit[i][0][j]+=(1<<k);
						bit[i][1][w[i]-1-k]+=(1<<j);
						bit[i][2][h[i]-1-j]+=(1<<(w[i]-1-k));
						bit[i][3][k]+=(1<<(h[i]-1-j));
					}
				}
			}
		}
		int m;scanf("%d",&m);
		while(m--){
	//		S.clear();
			for(int i=0;i<a;i++)now[i]=0;
			for(int i=0;i<a;i++)for(int j=0;j<b;j++)if(str[i][j]=='#')now[i]+=(1<<j);
			int sum=0;
			scanf("%d",&r);
			for(int i=0;i<r;i++){
				scanf("%d",com+i);com[i]--;
				sum+=has[com[i]];
			}
			if(sum!=cnt){printf("NO\n");continue;}
			for(int i=0;i<r;i++){
				for(int j=0;j<r-1;j++){
					if(sts[com[j]]>sts[com[j+1]]){
						swap(com[j],com[j+1]);
					}
				}
			}
			int res=solve(0);
			if(res)printf("YES\n");
			else printf("NO\n");
		}
	}
}
accuracy: 1
time_ms: 560
memory_kb: 1012
final_rank: 5

code_snippet: #include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

enum {Blank, Fill};

class Piece{
    vector<vector<int>> tile_value[4];
    int h_value[4], w_value[4];
    int dx_value[4];
    int direction;
public:
    Piece(const vector<vector<int>>& tile) {
        direction = 0;
        for(int d = 0; d < 4; ++d) {
            h_value[d] = d & 1 ? tile[0].size() : tile.size();
            w_value[d] = d & 1 ? tile.size() : tile[0].size();
        }
        for(int d = 0; d < 4; ++d) tile_value[d].resize(h_value[d]);
        for(int d = 0; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) tile_value[d][i].resize(w_value[d]);
        tile_value[0] = tile;
        for(int d = 1; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) for(int j = 0; j < w_value[d]; ++j)
            tile_value[d][i][j] = tile_value[d - 1][j][h_value[d] - 1 - i];
        for(int d = 0; d < 4; ++d) for(int j = 0; j < w_value[d]; ++j) {
            if(tile_value[d][0][j] == Blank) continue;
            dx_value[d] = j;
            break;
        }
    }
    int h() const {return h_value[direction];}
    int w() const {return w_value[direction];}
    int tile(int i, int j) const {return tile_value[direction][i][j];}
    int dx() const {return dx_value[direction];}
    void rotate() {direction = (direction + 1) % 4;}
};

int h, w;
vector<Piece> piece;
map<pair<vector<vector<int>>, vector<int>>, bool> memo;

bool dfs(const vector<vector<int>>& puzzle, const vector<int>& candidate) {
    if(memo.count(make_pair(puzzle, candidate))) return memo[make_pair(puzzle, candidate)];
    bool ok = true;
    int y, x;
    for(int i = 0; ok && i < h; ++i) for(int j = 0; ok && j < w; ++j) {
        if(puzzle[i][j] == Fill) continue;
        y = i;
        x = j;
        ok = false;
    }
    if(ok) return memo[make_pair(puzzle, candidate)] = (candidate.size() == 0);

    for(int c = 0; c < candidate.size(); ++c) {
        Piece p = piece[candidate[c]];
        for(int d = 0; d < 4; ++d) {
            p.rotate();
            if(h < y + p.h()) continue;
            if(w < x - p.dx() + p.w()) continue;
            if(x - p.dx() < 0) continue;
            vector<vector<int>> _puzzle = puzzle;
            ok = true;
            for(int i = 0; ok && i < p.h(); ++i) for(int j = 0; ok && j < p.w(); ++j) {
                _puzzle[y + i][x - p.dx() + j] += p.tile(i, j);
                if(_puzzle[y + i][x - p.dx() + j] == 2) ok = false;
            }
            if(!ok) continue;
            vector<int> _candidate = candidate;
            _candidate.erase(_candidate.begin() + c);
            if(dfs(_puzzle, _candidate)) return memo[make_pair(puzzle, candidate)] = true;
        }
    }
    return memo[make_pair(puzzle, candidate)] = false;
}

int main() {
    while(cin >> h >> w, h | w) {
        vector<vector<int>> puzzle(h, vector<int>(w));
        for(int i = 0; i < h; ++i) {
            string input;
            cin >> input;
            for(int j = 0; j < w; ++j) puzzle[i][j] = (input[j] == '#' ? Fill : Blank);
        }

        int n;
        piece.clear();
        for(cin >> n; 0 < n; --n) {
            int h1, w1;
            cin >> h1 >> w1;
            vector<vector<int>> tile(h1, vector<int>(w1));
            for(int i = 0; i < h1; ++i) {
                string input;
                cin >> input;
                for(int j = 0; j < w1; ++j) tile[i][j] = (input[j] == '#' ? Fill : Blank);
            }
            piece.push_back(Piece(tile));
        }

        memo.clear();
        int p;
        for(cin >> p; 0 < p; --p) {
            int k;
            vector<int> candidate;
            for(cin >> k; 0 < k; --k) {
                int x;
                cin >> x;
                candidate.push_back(x - 1);
            }
            sort(candidate.begin(), candidate.end());
            cout << (dfs(puzzle, candidate) ? "YES" : "NO") << endl;
        }
    }
}
accuracy: 1
time_ms: 2260
memory_kb: 63692
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

enum {Blank, Fill};

class Piece{
    vector<vector<int>> tile_value[4];
    int h_value[4], w_value[4];
    int dx_value[4];
    int direction;
public:
    Piece(vector<vector<int>> tile) {
        direction = 0;
        for(int d = 0; d < 4; ++d) {
            h_value[d] = d & 1 ? tile[0].size() : tile.size();
            w_value[d] = d & 1 ? tile.size() : tile[0].size();
        }
        for(int d = 0; d < 4; ++d) tile_value[d].resize(h_value[d]);
        for(int d = 0; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) tile_value[d][i].resize(w_value[d]);
        tile_value[0] = tile;
        for(int d = 1; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) for(int j = 0; j < w_value[d]; ++j)
            tile_value[d][i][j] = tile_value[d - 1][j][h_value[d] - 1 - i];
        for(int d = 0; d < 4; ++d) for(int j = 0; j < w_value[d]; ++j) {
            if(tile_value[d][0][j] == Blank) continue;
            dx_value[d] = j;
            break;
        }
    }
    int h() {return h_value[direction];}
    int w() {return w_value[direction];}
    int tile(int i, int j) {return tile_value[direction][i][j];}
    int dx() {return dx_value[direction];}
    void rotate() {direction = (direction + 1) % 4;}
};

int h, w;
vector<Piece> piece;
map<pair<vector<vector<int>>, vector<int>>, bool> memo;

bool dfs(vector<vector<int>> puzzle, vector<int> candidate) {
    if(memo.count(make_pair(puzzle, candidate))) return memo[make_pair(puzzle, candidate)];
    bool ok = true;
    int y, x;
    for(int i = 0; ok && i < h; ++i) for(int j = 0; ok && j < w; ++j) {
        if(puzzle[i][j] == Fill) continue;
        y = i;
        x = j;
        ok = false;
    }
    if(ok) return memo[make_pair(puzzle, candidate)] = (candidate.size() == 0);

    for(int c = 0; c < candidate.size(); ++c) {
        Piece p = piece[candidate[c]];
        for(int d = 0; d < 4; ++d) {
            p.rotate();
            if(h < y + p.h()) continue;
            if(w < x - p.dx() + p.w()) continue;
            if(x - p.dx() < 0) continue;
            vector<vector<int>> _puzzle = puzzle;
            ok = true;
            for(int i = 0; ok && i < p.h(); ++i) for(int j = 0; ok && j < p.w(); ++j) {
                _puzzle[y + i][x - p.dx() + j] += p.tile(i, j);
                if(_puzzle[y + i][x - p.dx() + j] == 2) ok = false;
            }
            if(!ok) continue;
            vector<int> _candidate = candidate;
            _candidate.erase(_candidate.begin() + c);
            if(dfs(_puzzle, _candidate)) return memo[make_pair(puzzle, candidate)] = true;
        }
    }
    return memo[make_pair(puzzle, candidate)] = false;
}

int main() {
    while(cin >> h >> w, h | w) {
        vector<vector<int>> puzzle(h, vector<int>(w));
        for(int i = 0; i < h; ++i) {
            string input;
            cin >> input;
            for(int j = 0; j < w; ++j) puzzle[i][j] = (input[j] == '#' ? Fill : Blank);
        }

        int n;
        piece.clear();
        for(cin >> n; 0 < n; --n) {
            int h1, w1;
            cin >> h1 >> w1;
            vector<vector<int>> tile(h1, vector<int>(w1));
            for(int i = 0; i < h1; ++i) {
                string input;
                cin >> input;
                for(int j = 0; j < w1; ++j) tile[i][j] = (input[j] == '#' ? Fill : Blank);
            }
            piece.push_back(Piece(tile));
        }

        int p;
        memo.clear();
        for(cin >> p; 0 < p; --p) {
            int k;
            vector<int> candidate;
            for(cin >> k; 0 < k; --k) {
                int x;
                cin >> x;
                candidate.push_back(x - 1);
            }
            sort(candidate.begin(), candidate.end());
            cout << (dfs(puzzle, candidate) ? "YES" : "NO") << endl;
        }
    }
}
accuracy: 1
time_ms: 2330
memory_kb: 63720
final_rank: 20

code_snippet: #include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

enum {Blank, Fill};

class Piece{
    vector<vector<int>> tile_value[4];
    int h_value[4], w_value[4];
    int dx_value[4];
    int direction;
public:
    Piece(vector<vector<int>> tile) {
        direction = 0;
        for(int d = 0; d < 4; ++d) {
            h_value[d] = d & 1 ? tile[0].size() : tile.size();
            w_value[d] = d & 1 ? tile.size() : tile[0].size();
        }
        for(int d = 0; d < 4; ++d) tile_value[d].resize(h_value[d]);
        for(int d = 0; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) tile_value[d][i].resize(w_value[d]);
        tile_value[0] = tile;
        for(int d = 1; d < 4; ++d) for(int i = 0; i < h_value[d]; ++i) for(int j = 0; j < w_value[d]; ++j)
            tile_value[d][i][j] = tile_value[d - 1][j][h_value[d] - 1 - i];
        for(int d = 0; d < 4; ++d) for(int j = 0; j < w_value[d]; ++j) {
            if(tile_value[d][0][j] == Blank) continue;
            dx_value[d] = j;
            break;
        }
    }
    int h() {return h_value[direction];}
    int w() {return w_value[direction];}
    int tile(int i, int j) {return tile_value[direction][i][j];}
    int dx() {return dx_value[direction];}
    void rotate() {direction = (direction + 1) % 4;}
};

int h, w;
vector<Piece> piece;
map<pair<vector<vector<int>>, vector<int>>, bool> memo;

bool dfs(vector<vector<int>> puzzle, vector<int> candidate) {
    if(memo.count(make_pair(puzzle, candidate))) return memo[make_pair(puzzle, candidate)];
    bool ok = true;
    int y, x;
    for(int i = 0; ok && i < h; ++i) for(int j = 0; ok && j < w; ++j) {
        if(puzzle[i][j] == Fill) continue;
        y = i;
        x = j;
        ok = false;
    }
    if(ok) return memo[make_pair(puzzle, candidate)] = (candidate.size() == 0);

    for(int c = 0; c < candidate.size(); ++c) {
        Piece p = piece[candidate[c]];
        for(int d = 0; d < 4; ++d) {
            p.rotate();
            if(h < y + p.h()) continue;
            if(w < x - p.dx() + p.w()) continue;
            if(x - p.dx() < 0) continue;
            vector<vector<int>> _puzzle = puzzle;
            ok = true;
            for(int i = 0; ok && i < p.h(); ++i) for(int j = 0; ok && j < p.w(); ++j) {
                _puzzle[y + i][x - p.dx() + j] += p.tile(i, j);
                if(_puzzle[y + i][x - p.dx() + j] == 2) ok = false;
            }
            if(!ok) continue;
            vector<int> _candidate = candidate;
            _candidate.erase(_candidate.begin() + c);
            if(dfs(_puzzle, _candidate)) return memo[make_pair(puzzle, candidate)] = true;
        }
    }
    return memo[make_pair(puzzle, candidate)] = false;
}

int main() {
    while(cin >> h >> w, h | w) {
        vector<vector<int>> puzzle(h, vector<int>(w));
        for(int i = 0; i < h; ++i) {
            string input;
            cin >> input;
            for(int j = 0; j < w; ++j) puzzle[i][j] = (input[j] == '#' ? Fill : Blank);
        }

        int n;
        piece.clear();
        for(cin >> n; 0 < n; --n) {
            int h1, w1;
            cin >> h1 >> w1;
            vector<vector<int>> tile(h1, vector<int>(w1));
            for(int i = 0; i < h1; ++i) {
                string input;
                cin >> input;
                for(int j = 0; j < w1; ++j) tile[i][j] = (input[j] == '#' ? Fill : Blank);
            }
            piece.push_back(Piece(tile));
        }

        int p;
        for(cin >> p; 0 < p; --p) {
            int k;
            vector<int> candidate;
            for(cin >> k; 0 < k; --k) {
                int x;
                cin >> x;
                candidate.push_back(x - 1);
            }
            memo.clear();
            sort(candidate.begin(), candidate.end());
            cout << (dfs(puzzle, candidate) ? "YES" : "NO") << endl;
        }
    }
}
accuracy: 1
time_ms: 2000
memory_kb: 12848
final_rank: 16

code_snippet: #include<iostream>
#include<map>
using namespace std;

int H,W;
class Puzzle{
 public:
  
  int S;
  char t[20][20];

  bool operator < (const Puzzle &p)const{
    for(int i=0;i<H;i++){
      for(int j=0;j<W;j++){
	if(t[i][j]==p.t[i][j])continue;
	return t[i][j]<p.t[i][j];
      }
    }
    return S<p.S;
  }
};

Puzzle p;
map<Puzzle,bool> vd;


char u[40][20][20];

int  h[40],w[40];
int n,m,a,b;
int v;
 
bool ans[2048];
 
void input();
void init();
void rotate(int,int);
 
void dfs(int,int);

void check();
bool on_check(int,int,int);
 
void on_tab(int,int,int);
void off_tab(int,int,int);
 
 
int main(){
  int S;
  while(cin>>H>>W){
    if(H==0&&W==0)break;

    input();
    init();
 
    p.S=0;
    dfs(0,0);

    cin>>m;
    for(int i=0;i<m;i++){
      cin>>a;
      S=0;
      for(int j=0;j<a;j++){
	cin>>v;
	v--;
	S+=(1<<v);
      }
      
      if(ans[S])cout<<"YES"<<endl;
      else cout<<"NO"<<endl;
    }
     
  }
  return 0;
}
 
 
void dfs(int y,int x){
    
  int tmp=p.S;
  
  bool flg=true;

  for(int i=0;i<H;i++){
    for(int j=0;j<W;j++){
      if(p.t[i][j]!='#')flg=false;
    }
  }
  if(flg){
    ans[p.S]=true;
    return;
  }

  vd[p]=true; 

  for(int i=0;i<n;i++){
    if((p.S>>i)&1==1)continue;
    for(int j=0;j<4;j++){
      
      if(on_check(y,x,4*i+j)==false)continue;
       
      p.S+=(1<<i);
      
      on_tab(y,x,4*i+j);

      if(vd[p]==false)dfs(y,x);

      off_tab(y,x,4*i+j);

      p.S=tmp;
    }
  }

  if(p.t[y][x]=='#')dfs((x+1==W?y+1:y),(x+1==W?0:x+1));
  
}
 
 
 
void rotate(int a,int b){
  for(int i=0;i<h[a];i++){
    for(int j=0;j<w[a];j++){
      u[a][i][j]=u[b][j][h[a]-i-1];
    }
  }
}
 
 
void init(){
  vd.clear();
  for(int i=0;i<2048;i++)ans[i]=false;
  
}
 
 
void input(){
  for(int i=0;i<20;i++)
    for(int j=0;j<20;j++)p.t[i][j]='.';

  string str;
  for(int i=0;i<H;i++){
    cin>>str;
    for(int j=0;j<W;j++){
      p.t[i][j]=str[j];
    }
  }
  cin>>n;
  for(int k=0;k<n;k++){
    cin>>h[k*4]>>w[k*4];
    for(int i=0;i<h[k*4];i++){
      cin>>str;
      for(int j=0;j<w[k*4];j++){
	u[k*4][i][j]=str[j];
      }
    }
    for(int i=1;i<4;i++){
      h[k*4+i]=w[k*4+i-1];
      w[k*4+i]=h[k*4+i-1];
      rotate(k*4+i,k*4+i-1);
    }
  }
}
 

 
bool on_check(int y,int x,int A){
  if(y+h[A]>H||x+w[A]>W)return false;
  for(int i=y;i<y+h[A];i++){
    for(int j=x;j<x+w[A];j++){
      if(u[A][i-y][j-x]=='#'&&p.t[i][j]=='#')return false;
    }
  }
  return true;
}
 
 
void on_tab(int y,int x,int A){
  for(int i=y;i<y+h[A];i++){
    for(int j=x;j<x+w[A];j++){
      if(u[A][i-y][j-x]=='#')p.t[i][j]='#';
    }
  }
}
 
 
void off_tab(int y,int x,int A){
  for(int i=y;i<y+h[A];i++){
    for(int j=x;j<x+w[A];j++){
      if(u[A][i-y][j-x]=='#')p.t[i][j]='.';
    }
  }
}
accuracy: 1
time_ms: 460
memory_kb: 6636
final_rank: 11