顶面的number of faces=连通分量的个数。这一道题开始以为只要BFS每一个点(i,j),如果(i,j)周围有column比height of (i,j)高,那么侧面数+1。后来发现相邻column的侧面也可能是连通的==。所以每次找到一个比(i,j)高的column,就要标记与之连通的侧面,然后这一块错了好久><。假设BFS的点(i,j)在第x行/列,相邻的比其高且未标记的column在第y行/列(y=x+ or -1)。遍历与column同一行/列的其他column_h,如果满足下面两个条件,则标记:1. column_h比(i,j)所在行/列对应的column高。 2. column_h高出的面是[a,b],column_h-1高出的面是[c,d],[a,b]与[c,d]必须有交集(仅顶点相连不算)。分别向左右两个方向遍历,如果找到一个不连通的column,该方向直接break。
WA了很久是因为比交集是和(i,j)对应的column比,后来发现应该是相邻的column比较。
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
//UVA 13011 - Height map
const int maxn=110;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
int mp[maxn][maxn];
bool vis[maxn][maxn];
bool f[maxn][maxn][4];
int R;
int C;
int ans;
int bfs(pair<int,int>st)
{
int ret=1;
queue<pair<int,int> >que;
while(!que.empty()) que.pop();
que.push(st);
vis[st.first][st.second]=true;
while(!que.empty())
{
pair<int,int>now=que.front();
que.pop();
int x=now.first;
int y=now.second;
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(mp[xx][yy]>mp[x][y])
{
if(f[xx][yy][i]==true) continue;
else
{
ret++;
f[xx][yy][i]=true;
int preh=mp[xx][yy];
int prel=mp[x][y];
if(i==0||i==2)
{
for(int j=xx-1;j>=0;j--)
{
int dir2=2-i;
int x2=j+dx[dir2];
int y2=yy+dy[dir2];
if(mp[j][yy]>mp[x2][y2])
{
if(mp[j][yy]<=prel||mp[x2][y2]>=preh) break;//need to cmp with the adjacent column, instead of mp[xx][yy] and mp[x][y]
else
{
f[j][yy][i]=true;
preh=mp[j][yy];
prel=mp[x2][y2];
}
}
else
{
break;
}
}
preh=mp[xx][yy];
prel=mp[x][y];
for(int j=xx+1;j<=R;j++)
{
int dir2=2-i;
int x2=j+dx[dir2];
int y2=yy+dy[dir2];
if(mp[j][yy]>mp[x2][y2])
{
if(mp[j][yy]<=prel||mp[x2][y2]>=preh) break;
else
{
f[j][yy][i]=true;
preh=mp[j][yy];
prel=mp[x2][y2];
}
}
else
{
break;
}
}
}
else if(i==1||i==3)
{
for(int j=yy-1;j>=0;j--)
{
int dir2=(i+2)%4;
int x2=xx+dx[dir2];
int y2=j+dy[dir2];
if(mp[xx][j]>mp[x2][y2])
{
if(mp[xx][j]<=prel||mp[x2][y2]>=preh) break;
else
{
f[xx][j][i]=true;
preh=mp[xx][j];
prel=mp[x2][y2];
}
}
else
{
break;
}
}
preh=mp[xx][yy];
prel=mp[x][y];
for(int j=yy+1;j<=C;j++)
{
int dir2=(i+2)%4;
int x2=xx+dx[dir2];
int y2=j+dy[dir2];
if(mp[xx][j]>mp[x2][y2])
{
if(mp[xx][j]<=prel||mp[x2][y2]>=preh) break;
else
{
f[xx][j][i]=true;
preh=mp[xx][j];
prel=mp[x2][y2];
}
}
else
{
break;
}
}
}
continue;
}
}
if(vis[xx][yy]==true) continue;
if(mp[xx][yy]==mp[x][y])
{
que.push(make_pair(xx,yy));
vis[xx][yy]=true;
}
}
}
//cout<<"bfs "<<st.first<<" "<<st.second<<" "<<ret<<endl;
return ret;
}
int main()
{
freopen("all.in","r",stdin);
freopen("myall.out","w",stdout);
while(scanf("%d %d",&R,&C)!=EOF)
{
memset(mp,0,sizeof(mp));
memset(vis,false,sizeof(vis));
memset(f,false,sizeof(f));
ans=5;
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
scanf("%d",&mp[i][j]);
}
}
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
if(vis[i][j]==true) continue;
else
{
ans+=bfs(make_pair(i,j));
//cout<<"tmp"<<bfs(make_pair(i,j));
}
}
}
printf("%d\n",ans);
}
}
//2 3
//1 2 3
//2 3 4
//3 3
//2 2 2
//2 1 2
//2 2 2
//2 3
//1 3 1
//5 5 4