dp记录每行向上的#的高度
然后O(n^2)直接扫过去即可
判断矩形条件:每行#高度相等且宽度相等
/*
USER_ID: test#ggvalid
PROBLEM: 407
SUBMISSION_TIME: 2014-07-14 17:45:35
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
int t, n, m;
int dp[1005][1005];
char s[2][1005];
int judge()
{
int ret=0;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
if(dp[i][j]){
int tmp=j;
int ans=dp[i][j], ans2=dp[i+1][j];
while(j<=m){
if(dp[i][j]!=0&&dp[i][j]!=ans) return -1;
if(dp[i][j]!=0&&dp[i+1][j]!=ans2) return -1;
j++;
if(!dp[i][j]) break;
}
j--;
if(!dp[i+1][j]) ret++;
}
}
}
return ret;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int ans=-1, mm=0;
memset(dp,0,sizeof dp);
for(int i=1; i<=n; i++){
scanf("%s",s[mm]);
mm^=1;
for(int j=1; j<=m; j++){
if(i!=1&&s[mm][j-1]=='#') dp[i][j]=(s[mm^1][j-1]=='#'?(dp[i-1][j]+1):0);
else dp[i][j]=s[mm^1][j-1]=='#'?1:0;
}
}
ans=judge();
if(ans==-1) puts("So Sad");
else printf("There are %d ships.\n",ans);
}
return 0;
}