BOJ407 Blocks

来源:互联网 发布:mac怎么清理qq缓存 编辑:程序博客网 时间:2024/06/17 23:48

给定一个NM的矩阵,求问里面有多少个由'#'组成的矩形,"There are 5 ships.",若是里面有一个不是矩形的联通块,则输出"So Sad"

输入格式

1n,m1000

有多组数据,EOF结束。

输出格式

每行对应一个answer

输入样例

6 8.....#.###.....###.....#.......##......##..#...#6 8.....#.###.....####...##.......###.....##..#...#
简单搜索题,但是刚开始的时候超时了,貌似是judge问题··········据说DFS会超时,但是优化之后能过。BFS时间要快一些,具体办法是保存每个矩形左上角的点的坐标,并在图上标记出右下角的坐标位置,对周围没有‘#’的‘#’不保存,直接计入矩阵数。然后对每一个左上角的点向左,向下BFS,如果BFS出的形状不为矩形则返回-1.复杂度为O(n*m)。可以做些小优化,比如计算左上角的点和右下角的点的数量,如果两者不相等,则不用BFS,直接输出“So Sad”;用双重for循环代替BFS,对于某个左上角的点,向右走到头,记录下矩阵的长,然后遍历下面每一排的点,直到遇到‘.’,如果停下的点不是先前所标记的,则返回-1。这样的话大概能优化常数倍时间
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;typedef long long LL;typedef pair<int,int> P;char A[1100][1100];bool used[1100][1100];bool ispoint[1100][1100];P V[100000];P point[100000];int N,M,si,sp;int solve(){    int i,j,k,res=0;    queue<int> que;    for(i=0;i<si;i++){        for(j=V[i].second;j<M;j++){            if(A[V[i].first][j]!='#')break;        }        int n=j;        for(j=V[i].first+1;j<N;j++){            if(A[j][V[i].second]!='#')break;            for(k=V[i].second+1;k<n;k++){                if(A[j][k]!='#'){                return -1;                }            }        }        if(ispoint[j-1][n-1]==true) res++;        else return -1;    }    return res;}int main(){    int i,j,k;    while(scanf("%d%d",&N,&M)!=EOF){        for(i=0;i<N;i++){            scanf("%s",A[i]);        }        si=0;        memset(used,0,sizeof(used));        memset(ispoint,0,sizeof(ispoint));        sp=0;        int sum=0;        for(i=0;i<N;i++){            for(j=0;j<M;j++){                if(A[i][j]=='#'&&(i==0||A[i-1][j]!='#')&&(j==0||A[i][j-1]!='#')){                    if((i==N-1||A[i+1][j]!='#')&&(j==M-1||A[i][j+1]!='#'))sum++;                    else{                       V[si].first=i;                       V[si++].second=j;                    }                }                else if(A[i][j]=='#'&&(i==N-1||A[i+1][j]!='#')&&(j==M-1||A[i][j+1]!='#')){                    sp++;                    ispoint[i][j]=true;                }            }        }      /*  for(i=0;i<si;i++){            printf("left up:%d %d\n",V[i].first,V[i].second);        }        for(i=0;i<N;i++){            for(j=0;j<M;j++)            if(ispoint[i][j])            printf("right low:%d %d\n",i,j);        }*/        int ans;        if(sp!=si) printf("So Sad\n");        else{ ans=solve();        if(ans!=-1)printf("There are %d ships.\n",ans+sum);        else printf("So Sad\n");        }    }    return 0;}

0 0