Language: C++

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <cstring>
#include <deque>

using namespace std;

#define reep(i,f,t) for(int i=f ; i<int(t) ; ++i)
#define rep(i,n) reep(i, 0, n) 

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;

struct Board
{
	int h, w, sy, sx;
	int map[20];
};

struct Part
{
	Board boards[4];
	int area;
	int id;
	
	bool operator> (const Part& p)const
	{
		return area > p.area;
	}
};

int n;
Board puzzle;
int puzzleArea;
Part parts[10];

int choice[10];
int m;
int rec;
int makeable[1024];
int makeNum;

void makeCombination(int p, int n, int sum)
{
	if(n == 0){
		makeable[makeNum++] = sum;
	}
	else if(n <= m-p){
		makeCombination(p+1, n, sum);
		makeCombination(p+1, n-1, sum+parts[choice[p]].area);
	}
}

// puzÌ(y, x)ðptsÌ(sy, sx)Éí¹Ä¨¯é©ð»è·é
bool fit(int puz[20], const Board pts, int y, int x)
{
	int fy = y - pts.sy;
	int fx = x - pts.sx;
	if(fy<0 || puzzle.h<fy+pts.h || fx<0 || puzzle.w<fx+pts.w)
		return false;
	
	rep(i, pts.h){
		if((puz[fy+i]>>fx) & pts.map[i])
			return false;
	}
	return true;
}

void putremove(int puz[20], const Board& pts, int y, int x, bool put)
{
	int fy = y - pts.sy;
	int fx = x - pts.sx;
	rep(i, pts.h){
		if(put) puz[fy+i] |= pts.map[i] << fx;
		else    puz[fy+i] ^= pts.map[i] << fx;
	}
}

// frmð90xñ]³¹½àÌðtoÉ«±Þ
void rotate(const Board& frm, Board& to)
{
	rep(i, frm.w)
		to.map[i] = 0;
	
	rep(i, frm.h) rep(j, frm.w){
		to.map[j] |= ((frm.map[i]>>j)&1) << (frm.h-i-1);
	}
	to.h = frm.w;
	to.w = frm.h;
}

void dump(const int tmp[20], int h, int w)
{
	rep(i, h){
		rep(j, w)
			putchar((tmp[i]>>j)&1 ? '#' : '.');
		puts("");
	}
}
void dump(const Board& board)
{
	dump(board.map, board.h, board.w);
}

int countUp(char tmp[20][20], int y, int x)
{
	const int dy[] = {-1, 0, 0, 1};
	const int dx[] = {0, -1, 1, 0};
	int ret = 0;
	tmp[y][x] = '#';
	rep(i, 4){
		int py = y + dy[i];
		int px = x + dx[i];
		if(py<0 || puzzle.h<=py || px<0 || puzzle.w<=px || tmp[py][px] == '#')
			continue;
		ret += countUp(tmp, py, px);
	}
	return ret + 1;
}

// } èp
bool isok()
{
	char tmp[20][20];
	rep(i, puzzle.h) rep(j, puzzle.w)
		tmp[i][j] = (puzzle.map[i]>>j) & 1 ? '#' : '.';
	
	rep(i, puzzle.h) rep(j, puzzle.w){
		if(tmp[i][j] == '.'){
			int ret = countUp(tmp, i, j);
			if(!binary_search(makeable, makeable + makeNum, ret))
				return false;
		}
	}
	return true;
}

// (y, z)ÉâÎu­ÆµÄÄA·é
bool search(int n, int y, int x)
{
	printf("n = %d\n", n);
	dump(puzzle);
	puts("");
	getchar();
	++rec;
	
	// } è
	//if(!isok()){
	//	return false;
	//}

	while(y<puzzle.h && (puzzle.map[y]>>x)&1){
		++x;
		if(x == puzzle.w){
			++y;
			x = 0;
		}
	}

	// ó¢Äéêª³¢
	if(y == puzzle.h)
		return true;

	reep(i, n, m){
		rep(j, 4){
			Board& board = parts[choice[i]].boards[j];
			if(fit(puzzle.map, board, y, x)){
				putremove(puzzle.map, board, y, x, true);
				swap(choice[i], choice[n]);
				bool ret = search(n+1, y, x);
				swap(choice[i], choice[n]);
				putremove(puzzle.map, board, y, x, false);
				if(ret)
					return true;
			}
		}
	}

	return false;
}

// p[cnðâÎÉg¤àÌÆµÄÄA·é
bool search2(int n)
{
	if(n==m)
		return true;
	
	rep(i, puzzle.h) rep(j, puzzle.w){
		rep(k, 4){
			Board& board = parts[choice[n]].boards[k];
			if(fit(puzzle.map, board, i, j)){
				putremove(puzzle.map, board, i, j, true);
				bool ret = search(n+1, 0, 0);
				putremove(puzzle.map, board, i, j, false);
				if(ret)
					return true;
			}
		}
	}

	return false;
}

// maskÌgÝí¹Ìp[cÅÂ­êé©Ç¤©
bool collect()
{
	int sum = 0;
	rep(i, m){
		sum += parts[choice[i]].area;
	}
	if(sum != puzzleArea)
		return false;

	return search2(0);
}
int main()
{
	int hoge=0;
	while(scanf("%d%d", &puzzle.h, &puzzle.w), puzzle.h){
		++hoge;
		if(hoge==1000){
			puts(reinterpret_cast<char*>(i));
		}
		puzzleArea = 0;
		rep(i, puzzle.h){
			char str[32];
			scanf("%s", str);
			puzzle.map[i] = 0;
			rep(j, puzzle.w){
				puzzle.map[i] |= (str[j]=='#')<<j;
				puzzleArea += str[j] == '.';
			}
		}

		scanf("%d", &n);
		rep(i, n){
			scanf("%d%d", &parts[i].boards[0].h, &parts[i].boards[0].w);
			parts[i].area = 0;
			parts[i].id = i;
			rep(j, parts[i].boards[0].h){
				char str[32];
				parts[i].boards[0].map[j] = 0;
				scanf("%s", str);
				rep(k, parts[i].boards[0].w){
					parts[i].boards[0].map[j] |= (str[k]=='#')<<k;
					parts[i].area += str[k] == '#';
				}
			}
			rep(j, 3){
				rotate(parts[i].boards[j], parts[i].boards[j+1]);
			}
			rep(j, 4){
				rep(k, parts[i].boards[j].h) rep(l, parts[i].boards[j].w){
					if((parts[i].boards[j].map[k]>>l)&1){
						parts[i].boards[j].sy = k;
						parts[i].boards[j].sx = l;
						k = parts[i].boards[j].h;
						break;
					}
				}
			}
		}

		sort(parts, parts+n, greater<Part>());
		map<int, int> table;
		rep(i, n)
			table[parts[i].id] = i;

		int p;
		scanf("%d", &p);
		rep(i, p){
			scanf("%d", &m);
			rep(j, m){
				int a;
				scanf("%d", &a);
				choice[j] = table[a-1];
			}
			sort(choice, choice+m);

			makeNum = 0;
			reep(j, 1, m+1)
				makeCombination(0, j, 0);
			sort(makeable, makeable + makeNum);
			makeNum = unique(makeable, makeable + makeNum) - makeable;

			rec = 0;
			puts(collect() ? "YES" : "NO");
			//printf("makeNum = %d, rec = %d\n", makeNum, rec);
		}
	}

	return 0;
}

Compiler output:
a.cc: In function 'int main()':
a.cc:228:54: error: 'i' was not declared in this scope; did you mean 'vi'?
  228 |                         puts(reinterpret_cast<char*>(i));
      |                                                      ^
      |                                                      vi