admin管理员组文章数量:1531767
一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色。
你有一个a*b的印章,有些格子是凸起(会沾上墨水)的。你需要判断能否用这个印章印出纸上的图案。印的过程中需要满足以下要求:
(1)印章不可以旋转。
(2)不能把墨水印到纸外面。
(3)纸上的同一个格子不可以印多次。
第一行一个整数q(1<=q<=10),表示测试点数量。
接下来q个测试点,每个测试点中:
第一行包含4个整数n,m,a,b(1<=n,m,a,b<=1000)。
接下来n行,每行m个字符,描述纸上的图案。'.'表示留白,'x'表示需要染黑。
接下来a行,每行b个字符,描述印章。'.'表示不沾墨水,'x'表示沾墨水。
对于每个测试点,输出TAK(是)或NIE(否)。
题解:
用vector存pair(坐标)的方式存印章,然后暴力所有点,对于遇到的第一个黑点判断是否满足题意
1越界不满足
2与印章不匹配
1°印章上有x,图上没有(直接在ck函数里判断即可)
2°图上有x,印章上没有x(统计黑点总数,看最后刷的黑点数是否等于总数)
Ac代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int maxn = 1e3+20;
int t,n,m,a,b,cnt;
char mmp[maxn][maxn],s[maxn];
bool vis[maxn][maxn];
vector<pll> brush;
bool ck(int x,int y){
for(auto i:brush){
if(x+i.first>n||y+i.second>m||x+i.first<1||y+i.second<1)
return false;
if(mmp[x+i.first][y+i.second]!='x')
return false;
vis[x+i.first][y+i.second] = 1,cnt--;
}
return true;
}
void sovle(){
memset(vis,0,sizeof(vis));
cnt = 0,brush.clear();
cin>>n>>m>>a>>b;
for(int i=1;i<=n;i++){
cin>>mmp[i]+1;
for(int j=1;mmp[i][j];j++)
if(mmp[i][j]=='x')
cnt++;
}
pll Anchor = {0,0};///锚定点,即第一个点,用于定位印章剩余点
for(int i=1;i<=a;i++){
cin>>s+1;
for(int j=1;s[j];j++)
if(s[j]=='x')
if(!Anchor.first && !Anchor.second)
brush.push_back(Anchor),Anchor = {i,j};
else
brush.push_back(make_pair(i-Anchor.first,j-Anchor.second));
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mmp[i][j]=='x' && !vis[i][j] && !ck(i,j)){
cout<<"NIE"<<endl;
return;
}
}
}
cout<<(!cnt?"TAK":"NIE")<<endl;
}
int main(){
cin>>t;
while(t--)
sovle();
return 0;
}
本文标签: Piecz
版权声明:本文标题:Pieczęć 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1725910896a1048636.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论