代码:
#include<cstring>
#include<iostream>
#include<limits.h>
typedef long long ll;
using namespace std;
int n,m;//n行m列
char s[110][110];//地图
bool v[110][110];//标记数组
int zonshu,zuoxiax,zuoxiay,youshangx,youshangy;//初始化
//每一个新格子都要重置
void chushi(){//归零
zonshu=0;
zuoxiax=zuoxiay=INT_MAX;//最大找最小
youshangx=youshangy=INT_MIN;//最小找最大
}
//比如这个图,我们要找的是箭头所指的横坐标和竖坐标
// #####.....#
// ^ -
// |
// #####...###
// ^ *
// |
//第一个箭头指着的横坐标是1,纵坐标是1。
//第二个箭头指着的横坐标是5,横坐标是2。
//那么他的长就是5-1+1=5,必须要加1,不然他的长就是4了,因为他减去的包括第一行,横坐标也是如此。
//那么他的面积就是2*5=10,而#的总数也是10。
//右下角的可以找到两个坐标9,1和11,2,那么这个9是*标记的横坐标,1是-标记的纵坐标,因为都是找最小。
//把么他的面积是3*2=6,而他只有3个#。
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};//方向
//进行搜索#号
void dfs(int x,int y){//深搜
v[x][y]=true;//标记
zonshu++;//总#数
zuoxiax=min(zuoxiax,x),zuoxiay=min(zuoxiay,y);
youshangx=max(youshangx,x),youshangy=max(youshangy,y);//两个点,最左上的和最右下
for(int i=0;i<4;i++){//四个方向
int nx=x+dx[i];
int ny=y+dy[i];
// cout<<endl;
// cout<<nx<<" "<<ny<<" "<<x<<" "<<y<<endl;
// cout<<s[nx][ny]<<" "<<v[nx][ny]<<endl;
if(s[nx][ny]=='#'&&!v[nx][ny]){//判断
dfs(nx,ny);//往下走
}
}
}
int gucang,nainiu;//谷仓数,奶牛数
//判断是谷仓还是奶牛
void pan_gucang_nainiu(){
if((youshangx-zuoxiax+1)*(youshangy-zuoxiay+1)==zonshu)gucang++;//满足面积等与总数
else nainiu++;
//cout<<zonshu<<endl<<youshangx<<" "<<youshangy<<" "<<zuoxiax<<" "<<zuoxiay<<endl<<youshangy-zuoxiay+1<<" "<<youshangx-zuoxiax+1<<endl<<endl;
}
int main(){
//输入
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>s[i][j];
}
}
// cout<<endl;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cout<<s[i][j];
// }
// cout<<endl;
// }
//循环找#
//cout<<3<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]=='#'&&!v[i][j]){//找到满足要求的
chushi();//初始化
//cout<<4<<endl;
dfs(i,j);//搜格
//cout<<5<<endl;
pan_gucang_nainiu();//判断是否满足谷仓
}
}
}
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cout<<s[i][j];
// }
// cout<<endl;
// }
//cout<<0<<endl;
//cout<<"*";
//输出
cout<<gucang;
//cout<<"*";
cout<<endl;
//cout<<"-";
cout<<nainiu;
//cout<<"-";
cout<<endl;
//cout<<1<<endl;
return 0;
}
这道题目,让我总结了许多。
比如,string用双重循环下标1输入就会越界。这个真的把我卡了挺久。最后还是换成char才过。
当然也可以从0开始。就是要改的地方太多了,懒得改。
思路:
用深搜找到最左上的点和最右下的点就行了,关于矩阵判断其实挺简单,只要矩阵面积=#总数就可以得出是矩阵了,具体的看注释,这就不讲了。
难点:
判断矩阵。
蒟蒻之作,不喜勿喷。