Problem:
Problem H:
Petoris
You are playing a puzzle game named
petoris
. It is played with a board divided into square
grids and square tiles each of which fits to a single grid.
In each step of the game, you have a board partially filled with tiles. You also have a block
consisting of several tiles. You are to place this block somewhere on the board or to discard it,
under the following restrictions on placement:
the block can be rotated, but cannot be divided nor flipped;
no tiles of the block can collide with any tiles existing on the board; and
all the tiles of the block need to be placed inside the board.
Your task is to write a program to find the maximum score you can earn in this step. Here, the
score is the number of the horizontal lines fully filled with tiles after the block is placed, or -1
in case of discard.
Input
The first line of the input is
N
, the number of data sets. Then
N
data sets follow.
Each data set consists of lines describing a block and a board. Each description (both for a block
and a board) starts with a line containing two integer
H
and
W
, the vertical and horizontal
dimension. Then
H
lines follow, each with
W
characters, where a ‘#’ represents a tile and ‘.’ a
vacancy. You can assume that 0 <
H
≤ 64 and 0 <
W
≤ 64. Each block consists of one or more
tiles all of which are connected. Each board contains zero or more tiles, and has no horizontal
line fully filled with tiles at the initial state.
Output
For each data set, print in a single line the maximum possible score.
Sample Input
5
4 4
....
....
####
....
12 8
........
........
........
........
........
.......#
##.##..#
.#######
.#######
.#######
.#######
.####.#.
4 4
....
....
.###
...#
12 8
........
........
........
........
........
........
........
##...###
##.#####
#######.
#######.
#######.
4 4
####
#..#
#..#
####
12 8
........
........
........
........
........
.......#
##.##..#
##....##
##.##.##
##.##.##
##....##
.####.#.
2 2
##
#.
3 3
.##
.##
##.
4 4
....
.##.
.##.
....
2 2
..
..
Output for the Sample Input
4
1
4
-1
2

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 70

struct Info{
	Info(){

		diff_row = 0;
		diff_col = 0;
	}
	Info(int arg_diff_row,int arg_diff_col){
		diff_row = arg_diff_row;
		diff_col = arg_diff_col;
	}
	int diff_row,diff_col;
};

struct DATA{

	vector<Info> info;
};

int H_P,W_P;
int H_T,W_T;
char P[SIZE][SIZE],T[SIZE][SIZE];
char work[SIZE][SIZE],TMP[SIZE][SIZE];

vector<DATA> calc(){

	vector<DATA> ret;

	for(int row = 0; row < max(H_P,W_P); row++){
		for(int col = 0; col < max(H_P,W_P); col++){

			work[row][col] = '.';
		}
	}

	for(int row = 0; row < H_P; row++){
		for(int col = 0; col < W_P; col++){

			work[row][col] = P[row][col];
		}
	}

	int H = max(H_P,W_P),W = max(H_P,W_P);

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

		bool FLG = false;

		//一番左上にある基準点を探す
		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){
				if(work[row][col] == '.')continue;

				int base_row = row;
				int base_col = col;

				DATA D;

				for(int i = 0; i < H; i++){
					for(int k = 0; k < W; k++){
						if(work[i][k] == '.')continue;

						D.info.push_back(Info(i-base_row,k-base_col));
					}
				}

				ret.push_back(D);

				FLG = true;
				break;
			}
			if(FLG)break;
		}

		for(int row = 0; row < max(H,W); row++){
			for(int col = 0; col < max(H,W); col++){

				TMP[row][col] = '.';
			}
		}

		//時計90度回転
		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){

				TMP[col][(W-1)-row] = work[row][col];
			}
		}

		for(int row = 0; row < max(H,W); row++){
			for(int col = 0; col < max(H,W); col++){

				work[row][col] = TMP[row][col];
			}
		}
	}

	return ret;
}

bool rangeCheck(int row,int col){

	return row >= 0 && row <= H_T-1 && col >= 0 && col <= W_T-1;
}


void func(){

	scanf("%d %d",&H_P,&W_P);
	for(int row = 0; row < H_P; row++){

		scanf("%s",P[row]);
	}

	scanf("%d %d",&H_T,&W_T);

	for(int row = 0; row < H_T; row++){

		scanf("%s",T[row]);
	}

	vector<DATA> vec = calc();

	int maxi = -1;

	for(int row = 0; row < H_T; row++){
		for(int col = 0; col < W_T; col++){
			if(T[row][col] == '#')continue;

			for(int i = 0; i < vec.size(); i++){

				vector<Info> V = vec[i].info;

				bool FLG = true;
				for(int k = 0; k < V.size(); k++){

					int tmp_row = row+V[k].diff_row;
					int tmp_col = col+V[k].diff_col;

					if(!rangeCheck(tmp_row,tmp_col)||T[tmp_row][tmp_col] == '#'){

						FLG = false;
						break;
					}
				}

				if(!FLG)continue;

				for(int k = 0; k < V.size(); k++){

					int tmp_row = row+V[k].diff_row;
					int tmp_col = col+V[k].diff_col;

					T[tmp_row][tmp_col] = '#';
				}

				int tmp_count = 0;

				for(int a = 0; a < H_T; a++){
					bool isOK = true;
					for(int b = 0; b < W_T; b++){
						if(T[a][b] == '.'){

							isOK = false;
							break;
						}
					}
					if(isOK){

						tmp_count++;
					}
				}

				maxi = max(maxi,tmp_count);

				for(int k = 0; k < V.size(); k++){

					int tmp_row = row+V[k].diff_row;
					int tmp_col = col+V[k].diff_col;

					T[tmp_row][tmp_col] = '.';
				}
			}
		}
	}


	printf("%d\n",maxi);
}

int main(){

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

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

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 3320
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n;
  cin>>n;
  while(n--){
    Int r,c;
    cin>>r>>c;
    vector<string> s(r);
    for(Int i=0;i<r;i++) cin>>s[i];
    Int h,w;
    cin>>h>>w;
    vector<string> t(h);
    for(Int i=0;i<h;i++) cin>>t[i];
    Int ans=-1;
    auto in=[&](Int y,Int x){
      return 0<=y&&y<h&&0<=x&&x<w;
    };
    auto check=[&](Int y,Int x){
      vector<string> u=t;
      for(Int i=0;i<r;i++){
	for(Int j=0;j<c;j++){
	  if(s[i][j]=='.') continue;
	  if(!in(y+i,x+j)) return;
	  if(u[y+i][x+j]=='#') return;
	  u[y+i][x+j]='#';
	}
      }
      Int res=0;
      for(Int i=0;i<h;i++){
	Int tmp=0;
	for(Int j=0;j<w;j++){
	  if(u[i][j]=='#') tmp++;
	}
	res+=(tmp==w);
      }
      ans=max(ans,res);
    };
    for(Int k=0;k<4;k++){
      for(Int i=-r+1;i<h;i++)
	for(Int j=-c+1;j<w;j++)
	  check(i,j);
      vector<string> v(c);
      for(Int i=r-1;i>=0;i--)
	for(Int j=0;j<c;j++)
	  v[j].push_back(s[i][j]);
      swap(r,c);
      s=v;
      //for(Int i=0;i<r;i++) cout<<s[i]<<endl;cout<<endl;
    }
    cout<<ans<<endl;
  }
   
  return 0;
}
accuracy: 1
time_ms: 7350
memory_kb: 3180
final_rank: 19

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

int h1, w1, h2, w2, dis;
string block[4][65];
string board[65];
string cp[65];
int H[4], W[4];

bool check(int &y, int &x){
  return (0<=y&&y<h2&&0<=x&&x<w2);
}

int y, x, idx;

int sim(){
  
  for(int i=0;i<h1;i++){
    for(int j=0;j<w1;j++){
      
      int py=y+i, px=x+j;
      
      if(block[idx][i][j]=='.') continue;      
      if(!check(py,px)&&block[idx][i][j]=='#') return 0;
      if(!check(py,px)) continue;
      if(board[py][px]=='#') return 0;
      
      board[py][px]='#';
    }
  }
  
  dis=1;
  
  int res=0;
  
  for(int i=0;i<h2;i++){
    
    int flag=1;
    
    for(int j=0;j<w2;j++)
      if(board[i][j]=='.'){
	flag=0;
	break;
      }
    
    res+=flag;
  }
 
  return res;
}

void solve(){
  
  int ans=0;
  
  dis=0;
  
  for(int k=0;k<4;k++){
    
    h1=H[k], w1=W[k];
    
    for(int i=-h1+1;i<h2;i++)
      for(int j=-w1+1;j<w2;j++){
	y=i, x=j, idx=k;
	ans=max(ans, sim());
	for(int l=0;l<h2;l++) board[l]=cp[l];
      }
  }
  
  if(!dis) ans=-1;
  
  cout<<ans<<endl;
  
}

void init(){
  
  H[0]=H[2]=h1;
  H[1]=H[3]=w1;
  W[0]=W[2]=w1;
  W[1]=W[3]=h1;
  
  for(int j=0;j<w1;j++)
    for(int i=h1-1;i>=0;i--) block[1][j]+=block[0][i][j];
  
  for(int i=h1-1;i>=0;i--)
    for(int j=w1-1;j>=0;j--) block[2][h1-i-1]+=block[0][i][j];
  
  for(int j=w1-1;j>=0;j--)
    for(int i=0;i<h1;i++) block[3][w1-j-1]+=block[0][i][j];
  
}

int main(){
  
  int t;
  cin>>t;

  while(t--){

    cin>>h1>>w1;
    for(int i=0;i<h1;i++) cin>>block[0][i];
    
    init();
        
    cin>>h2>>w2;
    for(int i=0;i<h2;i++){
      cin>>board[i];
      cp[i]=board[i];
    }
    
    solve();
    
    for(int i=0;i<4;i++)
      for(int j=0;j<65;j++) block[i][j]="";
    
  }
  
  return 0;
}
accuracy: 1
time_ms: 5970
memory_kb: 3208
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n;
  cin>>n;
  while(n--){
    Int r,c;
    cin>>r>>c;
    vector<string> s(r);
    for(Int i=0;i<r;i++) cin>>s[i];
    Int h,w;
    cin>>h>>w;
    vector<string> t(h);
    for(Int i=0;i<h;i++) cin>>t[i];
    Int ans=-1;
    auto in=[&](Int y,Int x){
      return 0<=y&&y<h&&0<=x&&x<w;
    };
    auto check=[&](Int y,Int x){
      vector<string> u=t;
      for(Int i=0;i<r;i++){
	for(Int j=0;j<c;j++){
	  if(s[i][j]=='.') continue;
	  if(!in(y+i,x+j)) return;
	  if(u[y+i][x+j]=='#') return;
	  u[y+i][x+j]='#';
	}
      }
      Int res=0;
      for(Int i=0;i<h;i++){
	Int tmp=0;
	for(Int j=0;j<w;j++){
	  if(u[i][j]=='#') tmp++;
	}
	res+=(tmp==w);
      }
      ans=max(ans,res);
    };
    for(Int k=0;k<4;k++){
      for(Int i=-r+1;i<h;i++)
	for(Int j=-c+1;j<w;j++)
	  check(i,j);
      vector<string> v(c);
      for(Int i=r-1;i>=0;i--)
	for(Int j=0;j<c;j++)
	  v[j].push_back(s[i][j]);
      swap(r,c);
      s=v;
      //for(Int i=0;i<r;i++) cout<<s[i]<<endl;cout<<endl;
    }
    cout<<ans<<endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 7220
memory_kb: 3264
final_rank: 20

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
vector<string>p,tmp,in;
void turn(){
	tmp=vector<string>(p[0].size(),"");
	rep(i,p[0].size())rep(j,p.size())
		tmp[i]+=p[j][p[0].size()-i-1];
	p=tmp;
}
int f(){
	int co=0;
	rep(i,tmp.size()){
		bool h=true;
		rep(j,tmp[i].size())if(tmp[i][j]!='#')h=false;
		if(h)co++;
	}
	return co;
}
int main(){
	int q;
	cin>>q;
	while(q--){
		int n,m;
		cin>>n>>m;
		p=vector<string>(n);
		rep(i,n)cin>>p[i];
		int nx=inf,ny=inf,mx=-inf,my=-inf;
		rep(i,n)rep(j,m)if(p[i][j]=='#'){
			nx=min(nx,i);mx=max(mx,i);
			ny=min(ny,j);my=max(my,j);
		}
		if(nx==inf)return -1;
		tmp=vector<string>(0);
		loop(i,nx,mx+1){
			tmp.pb(p[i].substr(ny,my-ny+1));
		}
		p=tmp;
		cin>>n>>m;
		in=vector<string>(n);
		rep(i,n)cin>>in[i];
		tmp=in;
		int out=f();
		bool H=false;
		rep(w,4){
			turn();
			int aa=p.size(),bb=p[0].size();
			if(n-aa+1<=0||m-bb+1<=0)continue;
			rep(i,n-p.size()+1)rep(j,m-p[0].size()+1){
				tmp=in;
				bool h=true;
				rep(k,p.size())rep(l,p[0].size()){
					if(p[k][l]=='#'&&in[i+k][j+l]=='#')h=false;
					else if(p[k][l]=='#')tmp[i+k][j+l]='#';
				}
				if(!h)continue;
				out=max(out,f());
				H=true;				
			}
		}
		if(H)cout<<out<<endl;
		else cout<<-1<<endl;
	}
}
accuracy: 1
time_ms: 4510
memory_kb: 1264
final_rank: 12

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX 100
 
char A[MAX][MAX],B[MAX][MAX];
 
void compress(int &h,int &w){
    int a = w,b = h;
    bool use[MAX],use2[MAX];
    vector<string> res;
 
    fill(use,use+h,true);
    fill(use2,use2+w,true);
 
    for(int i = 0 ; i < h ; i++){
	int cnt = 0;
	for(int j = 0 ; j < w ; j++){
	    if(A[i][j] != '.'){
		break;
	    }
	    cnt++;
	}
	if(cnt == w){ use[i] = false; a--; }
    }
 
    for(int i = 0 ; i < w ; i++){
	int cnt = 0;
	for(int j = 0 ; j < h ; j++){
	    if(A[j][i] != '.'){
		break;
	    }
	    cnt++;
	}
	if(cnt == h){ use2[i] = false; b--; }
    }
    for(int i = 0 ; i < h ; i++){
	if(!use[i]) continue;
	string s;
	for(int j = 0 ; j < w ; j++){
	    if(!use2[j]) continue;
	    s += A[i][j];
	}
	if(s.size() > 0){
	    res.push_back(s);
	}
    }
    h = res.size(); w = res[0].size();
    for(int i = 0 ; i < h ; i++){
	for(int j = 0 ; j < w ; j++){
	    A[i][j] = res[i][j];
	}
    }
}
 
void rotate(int &h,int &w){
    char tmp[MAX][MAX];
    for(int i = 0 ; i < h ; i++){
	for(int j = 0 ; j < w ; j++){
	    tmp[i][j] = A[i][j];
	}
    }
    for(int i = 0 ; i < h ; i++){
	for(int j = 0 ; j < w ; j++){
	    A[w-j-1][i] = tmp[i][j];
	}
    }
    int nh = w,nw = h;
    h = nh; w = nw;
}
 
int getPoint(int H,int W){
    int res = 0;
    for(int i = 0 ; i < H ; i++){
	int cnt = 0;
	for(int j = 0 ; j < W ; j++,cnt++){
	    if(B[i][j] != '#') break;
	}
	if(cnt == W){ res++; }
    }
    return res;
}
 
int getMaxScore(int h,int w,int H,int W){
    int maxPoint = -1;
    char C[MAX][MAX];
    for(int i = 0 ; i < H ; i++){
	for(int j = 0 ; j < W ; j++){
	    for(int k = 0 ; k < 4 ; k++){
		rotate(h,w);
		for(int l = 0 ; l < H ; l++){
		    for(int m = 0 ; m < W ; m++){
			C[l][m] = B[l][m];
		    }
		}
		bool ok = true;
		if(i+h > H || j+w > W) continue;
		for(int l = i ; l < i+h ; l++){
		    for(int m = j ; m < j+w ; m++){
			if(A[l-i][m-j] == '#' && B[l][m] == '#'){
			    ok = false; break;
			}
			if(A[l-i][m-j] == '#' && B[l][m] == '.'){
			    B[l][m] = A[l-i][m-j];
			}
		    }
		    if(!ok) break;
		}
		if(ok){
		    maxPoint = max(maxPoint,getPoint(H,W));
		}
		for(int l = 0 ; l < H ; l++){
		    for(int m = 0 ; m < W ; m++){
			B[l][m] = C[l][m];
		    }
		}
	    }
	}
    }
    return maxPoint;
}
 
int main(){
    int Tc,h,w,H,W;
    cin >> Tc;
    while(Tc--){
	cin >> h >> w;
	for(int i = 0 ; i < h ; i++){
	    for(int j = 0 ; j < w ; j++){
		cin >> A[i][j];
	    }
	}
	cin >> H >> W;
	for(int i = 0 ; i < H ; i++){
	    for(int j = 0 ; j < W ; j++){
		cin >> B[i][j];
	    }
	}
	compress(h,w);
	cout << getMaxScore(h,w,H,W) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 4460
memory_kb: 3168
final_rank: 17

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_H = 64;
const int MAX_W = 64;

/* typedef */

typedef unsigned long long ull;
typedef vector<ull> vull;

struct Block {
  int h, w;
  vull bits;

  void read() {
    cin >> h >> w;
    bits.assign(h, 0ULL);
    
    for (int y = 0; y < h; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < w; x++) {
	if (line[x] == '#') bits[y] |= (1ULL << x);
      }
    }
  }

  void normalize() {
    while (bits.front() == 0) bits.erase(bits.begin()), h--;
    while (bits.back() == 0) bits.erase(bits.end() - 1), h--;

    int min_lsp = w, min_rsp = w;
    for (vull::iterator vit = bits.begin(); vit != bits.end(); vit++) {
      int lsp, rsp;
      for (lsp = 0; (*vit & (1ULL << lsp)) == 0; lsp++);
      for (rsp = 0; (*vit & (1ULL << (w - 1 - rsp))) == 0; rsp++);
      if (min_lsp > lsp) min_lsp = lsp;
      if (min_rsp > rsp) min_rsp = rsp;
    }
    //printf("min_lsp = %d, min_rsp = %d\n", min_lsp, min_rsp);

    if (min_lsp > 0) {
      for (vull::iterator vit = bits.begin(); vit != bits.end(); vit++)
	*vit >>= min_lsp;
      w -= min_lsp;
    }
    w -= min_rsp;
    //printf("h=%d,w=%d\n", h, w);
  }

  void rotate() {
    vull bits0(bits);

    swap(h, w);
    bits.assign(h, 0ULL);

    for (int y = 0, x0 = h - 1; y < h; y++, x0--)
      for (int x = 0, y0 = 0; x < w; x++, y0++)
	if (bits0[y0] & (1ULL << x0)) bits[y] |= (1ULL << x);
  }

  void print() {
    printf("h=%d,w=%d\n", h, w);
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++)
	cout << ((bits[y] & (1ULL << x)) != 0 ? '#' : '.');
      cout << endl;
    }
  }
};

/* global variables */

/* subroutines */

int max_fill_len(Block& blk, Block& brd) {
  int mfl = -1;
  int dh = brd.h - blk.h, dw = brd.w - blk.w;
  if (dh < 0 || dw < 0) return mfl;

  ull allbits = (~0ULL >> (MAX_W - brd.w));
  
  for (int h0 = 0; h0 <= dh; h0++)
    for (int w0 = 0; w0 <= dw; w0++) {
      int fl = 0;
      bool ok = true;

      for (int y = 0; y < blk.h; y++) {
	ull blkbit = (blk.bits[y] << w0), brdbit = brd.bits[y + h0];
	if ((blkbit & brdbit) != 0) {
	  ok = false;
	  break;
	}
	if ((blkbit | brdbit) == allbits) fl++;
      }
  
      if (ok && mfl < fl) mfl = fl;
      //printf("(h0,w0)=(%d,%d): ok=%d, fl=%d\n", h0, w0, ok, fl);
    }

  return mfl;
}

/* main */

int main() {
  int n;
  cin >> n;

  while (n--) {
    Block blk, brd;
    blk.read();
    brd.read();

    blk.normalize();
    //blk.print();

    int max_fl = -1;
    
    for (int di = 0; di < 4; di++) {
      //blk.print();
      int fl = max_fill_len(blk, brd);
      if (max_fl < fl) max_fl = fl;

      blk.rotate();
    }

    cout << max_fl << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1236
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX 100

char A[MAX][MAX],B[MAX][MAX];

void compress(int &h,int &w){
  int a = w,b = h;
  bool use[MAX],use2[MAX];
  vector<string> res;

  fill(use,use+h,true);
  fill(use2,use2+w,true);

  for(int i = 0 ; i < h ; i++){
    int cnt = 0;
    for(int j = 0 ; j < w ; j++){
      if(A[i][j] != '.'){
        break;
      }
      cnt++;
    }
    if(cnt == w){ use[i] = false; a--; }
  }

  for(int i = 0 ; i < w ; i++){
    int cnt = 0;
    for(int j = 0 ; j < h ; j++){
      if(A[j][i] != '.'){
        break;
      }
      cnt++;
    }
    if(cnt == h){ use2[i] = false; b--; }
  }
  for(int i = 0 ; i < h ; i++){
    if(!use[i]){ continue; }
    string s;
    for(int j = 0 ; j < w ; j++){
      if(!use2[j]){ continue; }
      s += A[i][j];
    }
    if(s.size() > 0){
      res.push_back(s);
    }
  }
  h = res.size(); w = res[0].size();
  for(int i = 0 ; i < h ; i++){
    for(int j = 0 ; j < w ; j++){
      A[i][j] = res[i][j];
    }
  }
}

void rotate(int &h,int &w){
  char tmp[MAX][MAX];
  for(int i = 0 ; i < h ; i++){
    for(int j = 0 ; j < w ; j++){
      tmp[i][j] = A[i][j];
    }
  }
  for(int i = 0 ; i < h ; i++){
    for(int j = 0 ; j < w ; j++){
      A[w-j-1][i] = tmp[i][j];
    }
  }
  int nh = w,nw = h;
  h = nh; w = nw;
}

int getPoint(int H,int W){
  int res = 0;
  for(int i = 0 ; i < H ; i++){
    int cnt = 0;
    for(int j = 0 ; j < W ; j++,cnt++){
      if(B[i][j] != '#'){ break; }
    }
    if(cnt == W){ res++; }
  }
  return res;
}

int getMaxScore(int h,int w,int H,int W){
  int maxPoint = -1;
  char C[MAX][MAX];
  for(int i = 0 ; i < H ; i++){
    for(int j = 0 ; j < W ; j++){
      for(int k = 0 ; k < 4 ; k++){
        rotate(h,w);
        for(int l = 0 ; l < H ; l++){
          for(int m = 0 ; m < W ; m++){
            C[l][m] = B[l][m];
          }
        }
        bool ok = true;
        if(i+h > H || j+w > W){ continue; }
        for(int l = i ; l < i+h ; l++){
          for(int m = j ; m < j+w ; m++){
            if(A[l-i][m-j] == '#' && B[l][m] == '#'){
              ok = false; break;
            }
            if(A[l-i][m-j] == '#' && B[l][m] == '.'){
              B[l][m] = A[l-i][m-j];
            }
          }
          if(!ok){ break; }
        }
        if(ok){
          maxPoint = max(maxPoint,getPoint(H,W));
        }
        for(int l = 0 ; l < H ; l++){
          for(int m = 0 ; m < W ; m++){
            B[l][m] = C[l][m];
          }
        }
      }
    }
  }
  return maxPoint;
}

int main(){
  int Tc,h,w,H,W;
  cin >> Tc;
  while(Tc--){
    cin >> h >> w;
    for(int i = 0 ; i < h ; i++){
      for(int j = 0 ; j < w ; j++){
        cin >> A[i][j];
      }
    }
    cin >> H >> W;
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        cin >> B[i][j];
      }
    }
    compress(h,w);
    cout << getMaxScore(h,w,H,W) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7850
memory_kb: 1256
final_rank: 16

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
typedef unsigned long long wolf;
char in[100][100];
char str[100][100];
wolf t[100];
wolf u[100];
int tmp[100][100];
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int a,b;scanf("%d%d",&a,&b);
		for(int i=0;i<a;i++)scanf("%s",str[i]);
		int tr=9999;
		int tc=9999;
		int br=0;
		int bc=0;
		for(int i=0;i<a;i++){
			for(int j=0;j<b;j++){
				if(str[i][j]=='#'){
					tr=min(tr,i);
					tc=min(tc,j);
					br=max(br,i);
					bc=max(bc,j);
				}
			}
		}
		int h=br-tr+1;
		int w=bc-tc+1;
		for(int i=0;i<100;i++)t[i]=u[i]=0;
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				if(str[i+tr][j+tc]=='#')t[i]+=(1LL<<j);
			}
		}
		scanf("%d%d",&a,&b);
		for(int i=0;i<a;i++){
			scanf("%s",in[i]);
		}
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			if(in[i][j]=='#')u[i]+=(1LL<<j);
		}
		wolf f=0;
		for(int i=0;i<b;i++)f+=(1LL<<i);
		int ret=-1;
		for(int r=0;r<4;r++){
			for(int i=0;i<=a-h;i++){
				for(int j=0;j<=b-w;j++){
					bool ok=true;
					for(int k=0;k<h;k++){
						if((t[k]<<j)&u[i+k])ok=false;
					}
					if(!ok)continue;
					int cnt=0;
					for(int k=0;k<h;k++){
						if(((t[k]<<j)|u[i+k])==f)cnt++;
					}
					ret=max(ret,cnt);
				}
			}
			for(int i=0;i<100;i++)for(int j=0;j<100;j++)tmp[i][j]=0;
			for(int i=0;i<h;i++)for(int j=0;j<w;j++){
				if(t[i]&(1LL<<j))tmp[j][h-1-i]=1;
			}
			swap(h,w);
			for(int i=0;i<100;i++)t[i]=0;
			for(int i=0;i<h;i++)for(int j=0;j<w;j++){
				if(tmp[i][j])t[i]+=(1LL<<j);
			}
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 20
memory_kb: 1084
final_rank: 2

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
 
int H, W;
int N, M;
 
int L, T;
int R, B;
 
int ans;
 
char F[65][65];
char c[65][65];
 
void get_rect() {
   
  L = 65, T = 65;
  R = 0, B = 0;
   
  rep(i, 65) rep(j, 65) {
    if(c[i][j] == '#') {
      T = min(T, i);
      L = min(L, j);
      B = max(B, i);
      R = max(R, j);
    }
  }
   
}
 
void solve() {
 
  char G[65][65];
  int ans_tmp;
   
  rep(k, N-B+T) rep(l, M-R+L) { // oku hidari ue
     
    rep(i, N) rep(j, M) { G[i][j] = F[i][j]; }
     
     
    REP(i, T, B+1) REP(j, L, R+1) { // c no hidari ue
       
      int pos_i = i-T, pos_j = j-L; // small rect oku basyo
       
      if(G[k+pos_i][l+pos_j] == '#' && c[i][j] == '#') { goto Next; }
       
      if(c[i][j] == '#') {
    G[k+pos_i][l+pos_j] = '#';
      }
       
    }
     
     
    ans_tmp = 0;
     
    rep(i, N) {
      bool ok = 1;
      rep(j, M) {
    if(G[i][j] == '.') { ok = 0; }
      }
      ans_tmp += ok;
       
    }
      ans = max(ans, ans_tmp);
  Next:;
  }
   
   
}
 
int main() {
   
  int Tc; cin >> Tc;
  rep(_, Tc) {
     
    scanf("%d%d",&H, &W);
    rep(i, 65) rep(j, 65) c[i][j] = '.';
    rep(i, H) rep(j, W) cin >> c[i][j];
    scanf("%d%d",&N, &M);
    rep(i, N) rep(j, M) cin >> F[i][j];
     
    ans = -1;
    rep(t, 4) {
      char tmp[65][65];
       
      rep(i, 65) rep(j, 65)
    tmp[j][65-1-i] = c[i][j];
      rep(i, 65) rep(j, 65) {
    c[i][j] = tmp[i][j];
      }
      get_rect();
      solve();
    }
     
    cout << ans << endl;
  }
   
  return 0;
}
accuracy: 1
time_ms: 3080
memory_kb: 1252
final_rank: 11

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

typedef vector<string> B;

B rot(B b){
	int H = b.size();
	int W = b[0].size();
	B r(W,string(H,' '));
	for(int i = 0 ; i < H ; i++){
		for(int j = 0 ; j < W ; j++){
			r[j][H-i-1] = b[i][j];
		}
	}
	return r;
}

int score(B &b){
	string want = string(b[0].size(),'#');
	return count(b.begin(),b.end(),want);
}

int canset(B &b,B &p,int x,int y,int doit){
	for(int i = 0 ; i < p.size() ; i++){
		for(int j = 0 ; j < p[0].size() ; j++){
			if( p[i][j] == '#' ){
				int tx = j + x;
				int ty = i + y;
				if( tx < 0 || ty < 0 || ty >= b.size() || tx >= b[0].size() ) return false;
				if( b[ty][tx] == '#' ) return false;
				if(doit){
					b[ty][tx] = '#';
				}
			}
		}
	}
	return true;
}


void f(B b){
	for(int i = 0 ; i < b.size() ; i++)
		cout << b[i] << endl;
}
int main(){
	int T;
	cin >> T;
	while(T--){
		int h,w;
		cin >> h >> w;
		B p(h);
		for(int i = 0 ; i < h ; i++) cin >> p[i];
		
		int H,W;
		cin >> H >> W;
		B b(H);
		for(int i = 0 ; i < H ; i++) cin >> b[i];
		
		int ans = -1;
		for(int d = 0 ; d < 4 ; d++){
			for(int j = -h ; j < H ; j++){
				for(int k = -w ; k < W ; k++){
					if( canset(b,p,k,j,0) ){
						B t = b;
						canset(t,p,k,j,1);
						ans = max(score(t),ans);
					}
				}
			}
			swap(h,w);
			p = rot(p);
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 7400
memory_kb: 1288
final_rank: 15

code_snippet: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<climits>
#include<cassert>

#define IINF (INT_MAX)
#define MAX 70
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

int H,W;
vector<string> G;
vector<string> rot[4];

vector<string> conv(const vector<string>& vec)
{
  int n,e,s,w;
  w = IINF, e = -IINF, n = IINF, s = -IINF;

  for(int y=0;y<vec.size();y++){
    for(int x=0;x<vec[y].size();x++){
      if(vec[y][x] == '.')continue;
      w = min(w,x);
      e = max(e,x);
      n = min(n,y);
      s = max(s,y);
    }
  }

  vector<string> ret;
  for(int y=n;y<=s;y++){
    ret.push_back(vec[y].substr(w,e-w+1));
  }
  return ret;
}

vector<string> rotate90(const vector<string>& piece){
  vector<string> ret;
  int h = piece[0].size(), w = piece.size();
  ret.resize(h);
  for(int i=0;i<h;i++)ret[i].resize(w);
  for(int y=0;y<ret.size();y++){
    for(int x=0;x<ret[0].size();x++){
      ret[y][x] = piece[ret[0].size()-1-x][y];
    }
  }
  return ret;
}

void InitPiece(const vector<string>& piece){
  for(int i=0;i<4;i++){
    vector<string> tmp = piece;
    for(int j=0;j<i;j++){
      tmp = rotate90(tmp);
    }
    rot[i] = tmp;
  }
}

int calc(int sx,int sy,int type){
  int ret = 0;
  int h = rot[type].size(), w = rot[type][0].size();
  if(sx+w-1 >= W)return -1;
  if(sy+h-1 >= H)return -1;
  for(int y=sy;y<sy+h;y++){
    bool ok = true;
    for(int x=0;x<W;x++){
      if(sx <= x && x < sx+w){
	if(G[y][x] == '#' && rot[type][y-sy][x-sx] == '#'){
	  return -1;
	}
	else if(G[y][x] == '.' && rot[type][y-sy][x-sx] == '.'){
	  ok = false;
	}
      }else{
	if(G[y][x] != '#'){
	  ok = false;
	}
      }
    }
    if(ok)ret++;
  }
  return ret;
}

void compute(){
  int ans = -1;
  for(int y=0;y<H;y++){
    for(int x=0;x<W;x++){
      for(int type=0;type<4;type++){
	int res = calc(x,y,type);
	ans = max(ans,res);
      }
    }
  }
  cout << ans << endl;
}

int main(){
  int T,h,w;

  cin >> T;
  while(T--){
    cin >> h >> w;

    vector<string> tmp(h);
    for(int i=0;i<h;i++){
      cin >> tmp[i];
    }

    vector<string> piece = conv(tmp);
    InitPiece(piece);

    cin >> H >> W;
    G.resize(H);
    for(int i=0;i<H;i++){
      cin >> G[i];
    }
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 1352
final_rank: 6

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
#define rep(i, n) for ( int i = 0; i < n; i++)
#define MAX 64

class Piece{
    public: 
    int W, H;
    char G[MAX][MAX];

    void rotate(){
	char t[MAX][MAX];
	rep(i, H) rep(j, W) t[j][H-i-1] = G[i][j];
	swap(W, H);
	rep(i, H) rep(j, W) G[i][j] = t[i][j];
    }

    void trim(){
	int si, sj, ei, ej;
	si = sj = 100;
	ej = ei = -1;
	rep(i, H) rep(j, W) {
	    if ( G[i][j] == '.' ) continue;
	    si = min(i, si);
	    sj = min(j, sj);
	    ei = max(i, ei);
	    ej = max(j, ej);
	}

	char t[MAX][MAX];
	for ( int i = si; i <= ei; i++ ){
	    for ( int j = sj; j <= ej; j++ ){
		t[i-si][j-sj] = G[i][j];
	    }
	}
	W = ej-sj+1;
	H = ei-si+1;
	rep(i, H) rep(j, W) G[i][j] = t[i][j];
    }
};

char G[MAX][MAX], T[MAX][MAX];
int W, H;
Piece p;

bool check( int si, int sj, Piece u ){
    rep(i, H) rep(j, W) T[i][j] = G[i][j];
    rep(i, u.H) rep(j, u.W) {
	if ( G[i+si][j+sj] == '#' && u.G[i][j] == '#' ) return false;
	if ( G[i+si][j+sj] == '#' || u.G[i][j] == '#' ) {
	    T[i+si][j+sj] = '#';
	}
    }
    return true;
}

int getScore(){
    int score = 0;
    for ( int i = 0; i < H; i++ ){
	int cnt = 0;
	for ( int j = 0; j < W; j++ ){
	    if ( T[i][j] == '#' ) cnt++;
	    else break;
	}
	if ( cnt == W ) score++;
    }
    return score;
}

int compute(){
    int maxs = -1;
    for ( int r = 0; r < 4; r++ ){
	for ( int i = 0; i <= H - p.H; i++ ){
	    for ( int j = 0; j <= W - p.W; j++ ){
		if ( check(i, j, p) ){
		    maxs = max( maxs, getScore() );
		}
	    }
	}
	p.rotate();
    }
    return maxs;
}

int main(){
    int tcase;  cin >> tcase;
    for ( int t = 0; t < tcase; t++ ){
	cin >> p.H >> p.W;
	rep(i, p.H) rep(j, p.W) cin >> p.G[i][j];
	cin >> H >> W;
	rep(i, H) rep(j, W) cin >> G[i][j];
	p.trim();
	cout << compute() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1730
memory_kb: 1180
final_rank: 9

code_snippet: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<climits>
#include<cassert>

#define IINF (INT_MAX)
#define MAX 70
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

int H,W;
vector<string> G;
vector<string> rot[4];

vector<string> conv(const vector<string>& vec)
{
  int n,e,s,w;
  n = w = 0, e = vec[0].size(), s = vec.size();

  //North
  for(int i=0;i<vec.size();i++){
    bool check = true;
    for(int j=0;j<vec[i].size();j++){
      if(vec[i][j] != '.'){
	check = false;
	break;
      }
    }
    if(check){
      n++;
    } else break;
  }

  //South
  for(int i=vec.size()-1;i>=0;i--){
    bool check = true;
    for(int j=0;j<vec[i].size();j++){
      if(vec[i][j] != '.'){
	check = false;
	break;
      }
    }
    if(check){
      s--;
    } else break;
  }

  //West
  for(int x=0;x<vec[0].size();x++){
    bool check = true;
    for(int y=0;y<vec.size();y++){
      if(vec[y][x] != '.'){
	check = false;
	break;
      }
    }
    if(check){
      w++;
    } else break;
  }

  //East
  for(int x=vec[0].size()-1;x>=0;x--){
    bool check = true;
    for(int y=0;y<vec.size();y++){
      if(vec[y][x] != '.'){
	check = false;
	break;
      }
    }
    if(check){
      e--;
    } else break;
  }

  vector<string> ret;
  for(int y=n;y<s;y++){
    ret.push_back(vec[y].substr(w,e-w));
  }
  return ret;
}

vector<string> rotate90(const vector<string>& piece){
  vector<string> ret;
  int h = piece[0].size(), w = piece.size();
  ret.resize(h);
  for(int i=0;i<h;i++)ret[i].resize(w);
  for(int y=0;y<ret.size();y++){
    for(int x=0;x<ret[0].size();x++){
      ret[y][x] = piece[ret[0].size()-1-x][y];
    }
  }
  return ret;
}

void InitPiece(const vector<string>& piece){
  for(int i=0;i<4;i++){
    vector<string> tmp = piece;
    for(int j=0;j<i;j++){
      tmp = rotate90(tmp);
    }
    rot[i] = tmp;
  }
}

int calc(int sx,int sy,int type){
  int ret = 0;
  int h = rot[type].size(), w = rot[type][0].size();
  if(sx+w-1 >= W)return -1;
  if(sy+h-1 >= H)return -1;
  for(int y=sy;y<sy+h;y++){
    bool ok = true;
    for(int x=0;x<W;x++){
      if(sx <= x && x < sx+w){
	if(G[y][x] == '#' && rot[type][y-sy][x-sx] == '#'){
	  return -1;
	}
	else if(G[y][x] == '.' && rot[type][y-sy][x-sx] == '.'){
	  ok = false;
	}
      }else{
	if(G[y][x] != '#'){
	  ok = false;
	}
      }
    }
    if(ok)ret++;
  }
  return ret;
}

void compute(){
  int ans = -1;
  for(int y=0;y<H;y++){
    for(int x=0;x<W;x++){
      for(int type=0;type<4;type++){
	int res = calc(x,y,type);
	ans = max(ans,res);
      }
    }
  }
  cout << ans << endl;
}

int main(){
  int T,h,w;

  cin >> T;
  while(T--){
    cin >> h >> w;

    vector<string> tmp(h);
    for(int i=0;i<h;i++){
      cin >> tmp[i];
    }

    vector<string> piece = conv(tmp);
    InitPiece(piece);
    /*
    cout << "piece ---- " << endl;
    rep(i,piece.size())
      {
	cout << piece[i] << endl;
      }
    cout << endl;

    cout << "piece - rotate" << endl;
    string message[4] = {"0 - - -\n","90 - - -\n","180 - - -\n","270 - - -\n"};
    rep(i,4)
      {
	cout << message[i];
	rep(y,rot[i].size())
	  {
	    cout << rot[i][y] << endl;
	  }
	cout << endl;
      } cout << endl;
    */
    cin >> H >> W;
    G.resize(H);
    for(int i=0;i<H;i++){
      cin >> G[i];
    }

    compute();

  }
  return 0;
}

/*
18:21 - 18:26
19:00 - 20:04
 */
accuracy: 1
time_ms: 160
memory_kb: 1348
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

int main(){
  int N;
  cin >> N;
  while(N--){
    int H1, W1, H2, W2;
    cin >> H1 >> W1;
    vector<string> block(H1);
    REP(i, H1) cin >> block[i];
    cin >> H2 >> W2;
    vector<string> grid(H2);
    REP(i, H2) cin >> grid[i];
    int ans = -1;
    for(int iter = 0; iter < 4; iter++){
      int my1 = INF, my2 = -INF;
      REP(y, H1) REP(x, W1) if(block[y][x] == '#') my1 = min(my1, y), my2 = max(my2, y);
      for(int by = -my1; by + my2 < H2; by++){
        int y1 = max(by, 0), y2 = min(H2, by + H1);
        if(y2 - y1 <= ans) continue;
        for(int bx = -W1 + 1; bx < W2; bx++){
          bool exist = false;
          REP(y, H1)REP(x, W1) if(block[y][x] == '#' && (!valid(bx + x, by + y, W2, H2) || grid[by + y][bx + x] == '#')){
            exist = true;
            break;
          }
          if(exist) continue; // dame
          vector<string> grid_es = grid;
          REP(y, H1)REP(x, W1) if(block[y][x] == '#') grid_es[by + y][bx + x] = '#';
          int cnt = 0;
          for(int y = y1; y < y2; y++){
            bool ok = true;
            for(int x = 0; x < W2; x++){
              if(grid_es[y][x] != '#'){
                ok = false;
                break;
              }
            }
            if(ok) cnt++;
          }
          ans = max(ans, cnt);
        }
      }
      swap(H1, W1);
      vector<string> new_block(H1, string(W1, ' '));
      for(int y = 0; y < H1; y++){
        for(int x = 0; x < W1; x++){
          new_block[y][x] = block[x][H1 - y - 1];
        }
      }
      block = new_block;
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 5890
memory_kb: 1276
final_rank: 14

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

bool field[64][64];
bool block[64][64];
int need[64];

int BW, BH, FW, FH;
int minx, miny, maxx, maxy;

void adjust()
{
	minx = 999; miny = 999;
	maxx = 0;   maxy = 0;

	for(int i=0; i<64; i++) {
		bool f = false;
		for(int j=0; j<64; j++) {
			if(block[j][i]) {
				f = true;
			}
		}

		if(f) {
			miny = min(miny, i);
			maxy = max(maxy, i);
		}
	}

	for(int i=0; i<64; i++) {
		bool f = false;
		for(int j=0; j<64; j++) {
			if(block[i][j]) {
				f = true;
			}
		}

		if(f) {
			minx = min(minx, i);
			maxx = max(maxx, i);
		}
	}
}

void rotate()
{
	bool tmp[64][64];
	memset(tmp, 0, sizeof(tmp));

	for(int i=0; i<64; i++)
	for(int j=64-1; j>=0; j--) {
		tmp[i][64-1-j] = block[j][i];
	}

	memcpy(block, tmp, sizeof(block));
}

int solve()
{
	adjust();

	int W = maxx - minx + 1;
	int H = maxy - miny + 1;

	int res = -1;

	for(int i=0; i<=FH - H; i++) {
		for(int j=0; j<=FW - W; j++) {
			bool valid = true;
			int score = 0;

			for(int y=miny; y<=maxy; y++) {
				int cnt = 0;
				for(int x=minx; x<=maxx; x++) {
					if(!block[x][y]) continue;

					if(!field[j + x - minx][i + y - miny]) {
						valid = false;
					}
					else {
						cnt++;
					}
				}

				if(valid && need[i + y - miny] == cnt) score++;
			}

			if(valid) {
				res = max(score, res);
			}
		}
	}

	return res;
}

int main()
{
	int N;
	cin >> N;

	while(N--) {
		memset(need, 0, sizeof(need));
		memset(field, 0, sizeof(field));
		memset(block, 0, sizeof(block));

		cin >> BH >> BW;
		string b[64], f[64];

		for(int i=0; i<BH; i++)
			cin >> b[i];

		cin >> FH >> FW;
		for(int i=0; i<FH; i++)
			cin >> f[i];

		for(int i=0; i<BH; i++)
		for(int j=0; j<BW; j++) {
			if(b[i][j] == '#') {
				block[j][i] = 1;
			}
		}

		for(int i=0; i<FH; i++)
		for(int j=0; j<FW; j++) {
			if(f[i][j] == '.') {
				field[j][i] = 1;
				need[i]++;
			}
		}

		int res = -1;
		for(int i=0; i<4; i++) {
			res = max(res, solve());
			rotate();
		}

		cout << res << endl;
	}
}
accuracy: 1
time_ms: 340
memory_kb: 1248
final_rank: 4

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

void cutBlock(vector<string>& block, int& h, int& w)
{
    int minY = INT_MAX;
    int maxY = INT_MIN;
    int minX = INT_MAX;
    int maxX = INT_MIN;
    for(int i=0; i<h; ++i){
        for(int j=0; j<w; ++j){
            if(block[i][j] == '#'){
                minY = min(minY, i);
                maxY = max(maxY, i);
                minX = min(minX, j);
                maxX = max(maxX, j);
            }
        }
    }

    h = maxY - minY + 1;
    w = maxX - minX + 1;
    block = vector<string>(block.begin()+minY, block.begin()+maxY+1);
    for(int i=0; i<h; ++i)
        block[i] = string(block[i].begin()+minX, block[i].begin()+maxX+1);
}

void rotateBlock(vector<string>& block, int& h, int& w)
{
    vector<string> ret(w, string(h, ' '));
    for(int i=0; i<h; ++i){
        for(int j=0; j<w; ++j){
            ret[j][h-1-i] = block[i][j];
        }
    }
    swap(block, ret);
    swap(h, w);
}

int score(vector<string>& s)
{
    int h = s.size();
    int w = s[0].size();
    int ret = 0;
    for(int i=0; i<h; ++i){
        if(s[i] == string(w, '#'))
            ++ ret;
    }
    return ret;
}

int main()
{
    int n;
    cin >> n;

    while(--n >= 0){
        int h1, w1;
        cin >> h1 >> w1;
        vector<string> block(h1);
        for(int i=0; i<h1; ++i)
            cin >> block[i];
        cutBlock(block, h1, w1);

        int h2, w2;
        cin >> h2 >> w2;
        vector<string> s(h2);
        for(int i=0; i<h2; ++i)
            cin >> s[i];

        int ret = -1;
        for(int a=0; a<4; ++a){
            for(int y=0; y<=h2-h1; ++y){
                for(int x=0; x<=w2-w1; ++x){
                    bool ng = false;
                    for(int i=0; i<h1; ++i){
                        for(int j=0; j<w1; ++j){
                            if(s[y+i][x+j] == '#' && block[i][j] == '#')
                                ng = true;
                        }
                    }
                    if(ng)
                        continue;

                    vector<string> t = s;
                    for(int i=0; i<h1; ++i){
                        for(int j=0; j<w1; ++j){
                            if(block[i][j] == '#')
                                t[y+i][x+j] = '#';
                        }
                    }
                    ret = max(ret, score(t));
                }
            }
            rotateBlock(block, h1, w1);
        }

        cout << ret << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 2630
memory_kb: 1272
final_rank: 10

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

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

using namespace std;

struct block{
	int h,w;
	vector<string> B;
	block(int h,int w):h(h),w(w){
		B.resize(h);
		rep(i,h) B[i].resize(w);
	}
};

// 余分な枠を削除
block trim(const block &P){
	int h=P.h,w=P.w;
	int t,b,l,r;
	for(t= 0 ;;t++) if(count(P.B[t].begin(),P.B[t].end(),'#')>0) break;
	for(b=h-1;;b--) if(count(P.B[b].begin(),P.B[b].end(),'#')>0) break;
	for(l= 0 ;;l++){ bool ok=false; rep(i,h) if(P.B[i][l]=='#') { ok=true; break; } if(ok) break; }
	for(r=w-1;;r--){ bool ok=false; rep(i,h) if(P.B[i][r]=='#') { ok=true; break; } if(ok) break; }

	block res(b-t+1,r-l+1);
	rep(i,res.h) res.B[i]=P.B[t+i].substr(l,res.w);
	return res;
}

bool overlap(const block &P,const block &Q,int dy,int dx){
	rep(i,Q.h) rep(j,Q.w) if(P.B[i+dy][j+dx]=='#' && Q.B[i][j]=='#') return true;
	return false;
}

block merge(const block &P,const block &Q,int dy,int dx){
	block res=P;
	rep(i,Q.h) rep(j,Q.w) if(Q.B[i][j]=='#') res.B[i+dy][j+dx]='#';
	return res;
}

int count_line(const block &P){
	int h=P.h,w=P.w;
	int res=0;
	rep(i,h) if(count(P.B[i].begin(),P.B[i].end(),'#')==w) res++;
	return res;
}

block spin(const block &P){
	int h=P.h,w=P.w;
	block res(w,h);
	rep(i,h) rep(j,w) res.B[j][h-i-1]=P.B[i][j];
	return res;
}

int solve(){
	int h,w;
	cin>>h>>w;
	block P(h,w); // piece
	rep(i,P.h) cin>>P.B[i];

	cin>>h>>w;
	block F(h,w); // field
	rep(i,F.h) cin>>F.B[i];

	P=trim(P);

	int ans=-1;
	rep(t,4){
		rep(i,F.h-P.h+1) rep(j,F.w-P.w+1) if(!overlap(F,P,i,j)) {
			ans=max(ans,count_line(merge(F,P,i,j)));
		}
		P=spin(P);
	}
	return ans;
}

int main(){
	int T; cin>>T;
	while(T--) cout<<solve()<<endl;
	return 0;
}
accuracy: 1
time_ms: 2090
memory_kb: 968
final_rank: 8

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

int block2[64][64];
int block[64][64];
int ba[64][64];
int blocknum[64];               // isÌ^CÌ
int banum[64];

int main() {
  int t;
  cin >> t;
  while(t--) {
    int h,w;
    cin >> h >> w;
    REP(i, h) {
      REP(j, w) {
        char c; cin >> c;
        block2[i][j] = (c=='#');
      }
    }
    int h1 = -1, h2;
    REP(i, h) {
      bool f = 0;
      REP(j, w) if (block2[i][j]) f = 1;
      if (f) {
        if (h1 == -1) h1 = i;
        h2 = i;
      }
    }
    int w1 = -1, w2;
    REP(i, w) {
      bool f = 0;
      REP(j, h) if (block2[j][i]) f = 1;
      if (f) {
        if (w1 == -1) w1 = i;
        w2 = i;
      }
    }
    int cnth=0;
    for (int i=h1; i<=h2; ++i) {
      int cntw = 0;
      for (int j=w1; j<=w2; ++j) {
        block[cnth][cntw] = block2[i][j];
        cntw++;
      }
      cnth++;
    }
    h = cnth; w = w2-w1+1;
    
    int H, W;
    cin >> H >> W;
    REP(i, H) {
      banum[i] = 0;
      REP(j,W) {
        char c;
        cin >> c;
        ba[i][j] = (c == '#');
        if (c == '#') banum[i]++;
      }
    }
    int ans = -1;
    REP(i, 4) {
      // REP(j, h) {
      //   REP(k, w) cout << block[j][k];
      //   cout << endl;
      // }
      // esÌ^CÌvZ
      REP(j, h) {
        blocknum[j] = 0;
        REP(k, w) if (block[j][k]) blocknum[j]++;
      }
      
      for (int j=0; j<H-h+1; ++j) {
        for (int k=0; k<W-w+1; ++k) {
          bool dame = 0;
          for (int l=0; l<h; ++l) {
            for (int m=0; m<w; ++m) {
              if (block[l][m] && ba[j+l][k+m]) {
                dame = 1;
                break;
              }
            }
            if (dame) break;
          }
          if (!dame) {
            //cout << j << " " << k << endl;
            int hoge = 0;
            REP(l, h) {
              if (blocknum[l] + banum[j+l] == W) hoge++;
            }
            ans = max(ans, hoge);
          }
        }
      }
      // ñ]
      int next[64][64];
      REP(j, w) {
        REP(k, h) {
          next[j][k] = block[k][w-j-1];
        }
      }
      swap(w,h);
      memcpy(block, next, sizeof(next));
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 80
memory_kb: 0
final_rank: 1

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

using namespace std;

typedef unsigned long long ll;

int N;
int blH,blW;
int bdH,bdW;
int block[4][101][101];
int field[101][101];

ll bk[4][101];
ll bd[101];
ll bits[65];

void RotateBlock(){
    for(int k=0;k<3;k++)for(int j=0;j<blW;j++)for(int i=0;i<blH;i++)
        block[k+1][j][blH-1-i]=block[k][i][j];
    for(int i=0;i<4;i++){
        for(int j=0;j<blH;j++){
            bk[i][j]=0;
            for(int k=0;k<blW;k++)if(block[i][j][k])bk[i][j]|=(1ULL<<k);
        }
    }
}

int main(){
    bits[1]=1;
    for(int i=2;i<=64;i++)bits[i]=(bits[i-1]<<1)+1;
    cin>>N;
    int prv=-2;
    while(N--){
        memset(block,0,sizeof(block));
        cin>>blH>>blW;
        for(int i=0;i<blH;i++){
            for(int j=0;j<blW;j++){
                char ch;
                cin>>ch;
                if(ch=='#')block[0][i][j]=1;
                else block[0][i][j]=0;
            }
        }
        blH=max(blH,blW);
        blW=blH;
        cin>>bdH>>bdW;
        for(int i=0;i<bdH;i++){
            bd[i]=0;
            for(int j=0;j<bdW;j++){
                char ch;
                cin>>ch;
                if(ch=='#'){
                    field[i][j]=1;
                    bd[i]|=(1ULL<<j);
                }
                else field[i][j]=0;
            }
        }
        // ubNðñ]³¹ÂÂSêð·
        // ubNÌEºÌÀWª{[hãÌÇÌÀWÉêv·é©H
        // ñ]
        RotateBlock();
        int res=-1;
        for(int k=0;k<4;k++){
            for(int i=0;i<bdH+blH-1;i++){
                for(int j=0;j<bdW+blW-1;j++){
                    int cnt=0;
                    // ubNªÍÝoéàµ­ÍdÈè`FbN
                    bool isSetable=true;
                    for(int l=0;l<blH;l++){
                        int bdy=-blH+l+1+i;
                        if(bdy<0||bdy>=bdH){
                            if(bk[k][l]!=0){
                                isSetable=false;
                                break;
                            }
                        }
                        // ¡ñÌsªdÈéê
                        else{
                            // ñÌ¤¿dÈéêÆdÈçÈ¢êðª
                            int sbdx=-blW+0+1+j;
                            int fbdx=j;
                            if(sbdx>=0&&sbdx<bdW&&fbdx>=0&&fbdx<bdW){
                                // bitZ
                                ll a=bk[k][l]<<(sbdx);
                                // êv·éÈçAcnt
                                if((a^bd[bdy])==bits[bdW])cnt++;
                                else if((a&bd[bdy])!=0)isSetable=false;
                            }
                            // ¼[Oêé
                            else if((sbdx<0||sbdx>=bdW)&&(fbdx<0||fbdx>=bdW)){
                                ll a=((bk[k][l]>>abs(sbdx))<<(64-bdW))>>(64-bdW);
                                ll b1=(bk[k][l]<<(64-abs(sbdx)))>>(64-abs(sbdx));
                                ll b2=(bk[k][l]>>abs(sbdx)+bdW);
                                if(b1==0&&b2==0){
                                    if((a^bd[bdy])==bits[bdW])cnt++;
                                    else if(((a&bd[bdy])!=0))isSetable=false;
                                }
                                else isSetable=false;
                            }
                            // E[ªÍÝoé
                            else if(sbdx>=0&&sbdx<bdW){
                                // ÍÝoéêð0Åmask
                                int mv=(64-(bdW-sbdx));
                                ll a=((bk[k][l]<<mv)>>mv)<<(sbdx);
                                // ÍÝo½ê
                                ll b=bk[k][l]>>(bdW-sbdx);
                                if(b==0){
                                    if((a^bd[bdy])==(bits[bdW]))cnt++;
                                    else if((a&bd[bdy])!=0)isSetable=false;
                                }
                                else isSetable=false;
                            }
                            // ¶[ªÍÝoé
                            else{
                                ll a=(bk[k][l]>>(blW-fbdx-1));
                                int mv=(64-(blW-fbdx-1));
                                ll b=(bk[k][l]<<mv)>>mv;
                                if(b==0){
                                    if((a^bd[bdy])==(bits[bdW]))cnt++;
                                    else if((a&bd[bdy])!=0)isSetable=false;
                                }
                                else isSetable=false;
                            }
                        }
                    }
                    if(isSetable)res=max(res,cnt);
                }
            }
        }
        cout<<res<<endl;
        prv=res;
    }
    return 0;
}
accuracy: 1
time_ms: 1450
memory_kb: 1064
final_rank: 7