枚举 + bitset
用bitset记录GL的情况
然后直接枚举每个位置为左上角时候的答案
用一个bitset清除在查询范围之外的位
char s[maxm][maxm];
char s2[maxm][maxm];
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int n,m;
sdd(n,m);
for(int i=1; i<=n; ++i)scanf("%s",s[i]+1);
int t;
sd(t);
r1(cas,t) {
printf("Case #%d: ",cas);
int x,y;
sdd(x,y);
bitset<maxm> a[maxm];//blueprint
bitset<maxm> b[maxm];//farm
for(int i=1; i<=x; ++i)scanf("%s",s2[i]+1);
for(int i=1; i<=x; ++i)
for(int j=1; j<=y; ++j) {
if(s2[i][j]=='G')b[i].reset(j);
else b[i].set(j);
}
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) {
if(s[i][j]=='G')a[i].reset(j);
else a[i].set(j);
}
int tot = x*y;
int mx = -1;
int px = n+1 ,py = m+1;
int g= 0,l = 0 ;
bitset<maxm> ignore ;//消除其他位用的
ignore.reset();
for(int j=1; j<=y; ++j)ignore.set(j);
for(int j=1; j+y-1<=m; ++j) {
for(int i=1; i+x-1<=n; ++i) {
int cnt = 0;
for(int o=0; o<x; ++o) {
bitset<maxm>check = a[o+i]^b[o+1];//算不同的位置个数
check &= ignore;
cnt += check.count();
}
cnt = tot - cnt;
if(cnt>mx||( cnt==mx && ( ( i < px ) || ( i==px && j < py ) ))) {
mx = cnt;
px = i,py = j;
}
}
ignore.reset(j);
if(j+y<maxm)ignore.set(j+y);
for(int i=1; i<=x; ++i)b[i]<<=1;
}
for(int i=0; i<x; ++i)
for(int j=0; j<y; ++j) {
if(s[i+px][j+py]==s2[i+1][j+1]) {
if(s2[i+1][j+1]=='G')++g;
else ++l;
}
}
printf("%d %d %d %d\n",px,py,g,l);
}
return 0;
}