题目名称:
刷子和染料
题目描述:
有一把K×K大小的刷子和黑白两种颜色的染料,颜料很浓,具有覆盖性。现在给你一幅黑白颜色构成的大小为N×M的图画,问你能否用这把刷子画成这幅画。你只能水平或垂直移动刷子作画,且刷子不能刷到图画外的区域。
注:作画之前,画板上没有任何颜色。
输入格式:
本题每个测试点仅包含一组测试数据。
第一行输入三个整数依次是K, N, M接下来输入一张N*M的图,图以"W"和“B‘来描述,"W"为白色区域,”B"为黑色区域。
输出格式:
输出一行,如果能完成作画输出“YES”,否则输出“NO”.
输入输出样例:
输入
2 4 5
BBBBW
BBBWW
WBBWW
WBBWW
输出
YES
方法1:
骗分(好像又不算是骗分),分数:67分
代码:
#include<bits/stdc++.h>
using namespace std;
int k,n,m,w,b;
char a[1000][1000];
int main()
{
cin>>k>>n>>m;
for(int i=1;i<=n;i++)//输入
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
if(a[i][j]=='B')
{
b++;//如果是黑色的,b++
}
else
{
w++;//否则w++
}
}
}
if(k>n)//如果刷子大于画的宽度,不可能
{
cout<<"NO";
return 0;
}
if(k>m)//如果刷子大于画的宽度,也不可能
{
cout<<"NO";
return 0;
}
if(k==n&&k==m)//如果刷子的面积与画的面积相等,并且有黑白两种颜色,不可能
{
if(b>0&&w>0)
{
cout<<"NO";
return 0;
}
}
cout<<"YES";//其余都可能(乱说的hh)
return 0;
}
方法2:
正解hh
思路:
我们可以用贪心思想。
通过样例,我们可以发现最后的一块是k*k的连通块。而倒数的第i块的一部分被最后的i-1块给挡住了,剩下的部分一定是同色的。
我们可以先确定一个kk的同色块,将他们标记一下,在后面的查找kk的块时,只需做一个判断,判断没有被标记的方格是否为同色的块,直到找不到这样的同色块为止。
最后,我们用再双重循环查找一遍,如果有没被标记的黑色块,就输出“NO”,否则输出“YES”即可。
代码:
#include<bits/stdc++.h>
using namespace std;
char a[10000][10000];
bool ss[10000][10000];
int n,k,m;
bool bo=1;
int main()
{
cin>>k>>n>>m;
for(int i=1;i<=n;i++) //输入(一行一行的输入)
{
scanf("%s",a[i]+1);
}
while(bo==1)//只要还有k*k的那种块
{
bo=0;//先重置
for(int i=1;i<=n+1-k;i++)//寻找
{
for(int j=1;j<=m+1-k;j++)
{
int b=0,w=0;//k*k的块中黑白两种块的数量
bool q=0;//用来判断有没有k*k的同色块
for(int ii=i;ii<i+k;ii++)//枚举k*k的块
{
for(int jj=j;jj<j+k;jj++)
{
if(ss[ii][jj]==0) //如果没被标记过
{
q=1;//有
if(a[ii][jj]=='B') //判断颜色
{
b++;
}
else
{
w++;
}
}
}
}
if((b==0||w==0)&&q==1)//如果有k*k的块并且是同色的
{
bo=1;//可以继续查找
for(int ii=i;ii<i+k;ii++)//标记
{
for(int jj=j;jj<j+k;jj++)
{
ss[ii][jj]=1;
}
}
}
}
}
}
bool x=0,xx=0;//两个bool类型的变量,x判断“yes,no”,xx判断x是否变为1
for(int i=1;i<=n;i++)//再搜索一遍
{
for(int j=1;j<=m;j++)
{
if(ss[i][j]==0&&a[i][j]=='B') //如果有没被标记并且是黑色的块
{
x=1;//no
xx=1;//x变为1了
break;//跳出循环
}
}
if(xx==1)//如果x变为1了
{
break;//跳出循环,没有必要找下去了
}
}
if(x==0) //yes
{
cout<<"YES";
return 0;
}
cout<<"NO";//否则no
return 0;
}
结束啦~~~