心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0
此题的意思就是在用‘.’和‘#’组成的图形中,有多少个长方形。这类问题最容易想到的方法就是BFS,这题我依然按照这个思路去想。

 

利用BFS很容易得出有多少个由 # 组成的图形,问题的关键成为了如何判断一个图形是否是长方形。

如下图形:

. . . .

##. .

##. .

. . . .

一眼即可看出它是个长方形(废话)。

再看另一个:

. . . .

## . .

### .

. . . .

它不是一个长方形。

如果注意到两个图形的行坐标的最大值最小值、列坐标的最大值最小值与图形的面积之间的关系,我们很容易想出来一个算法。

(xmax-xmin+1)*(ymax-ymin+1)==area

是一个长方形;

否则不是。

时间复杂度O(rc)1000*1000的数据规模完全可以承受。

此题还有其他解法。

这种方法很好理解,但是程序有点长,因为涉及到BFS

Ps:另外说明一下BFS应该由一个点出发向8个点搜索,题目中说的不是太清楚。这一点我也是看了测试数据才知道。

 

以下是我的程序:

#include<stdio.h>
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
typedef 
struct
{
    
long front,rear,count,x[100000],y[100000];
}
Queue;
char map[1001][1001];
long r,c;
long id[]={-1,-1,0,1,1,1,0,-1};
long jd[]={0,1,1,1,0,-1,-1,-1};
int used[1001][1001]={0};
void clear(Queue *q)
{
    q
->count=0;
    q
->front=0;
    q
->rear=-1;
}

void put(Queue *q,long a,long b)
{
    q
->count++;
    q
->rear++;
    q
->x[q->rear]=a;
    q
->y[q->rear]=b;
}

void get(Queue *q,long *a,long *b)
{
    q
->count--;
    
*a=q->x[q->front];
    
*b=q->y[q->front];
    q
->front++;
}

int empty(Queue *q)
{
    
return (q->count<=0);
}

long bfs1()
{
    
long i,j,re=0;
    
for(i=0;i<r;i++)
      
for(j=0;j<c;j++)
        
if(map[i][j]=='#')
          re
++;
    
return re;
}

long bfs2(long *ans)
{
    
long i,j,k,t1,t2,re=0,xmin,xmax,ymin,ymax,flag;
    Queue A;
    clear(
&A);
    
for(i=0;i<r;i++)
      
for(j=0;j<c;j++)
      
{
         flag
=0;
         
if(map[i][j]=='#'&&!used[i][j])
         
{
            put(
&A,i,j);
            xmin
=xmax=i;
            ymin
=ymax=j;
            flag
=1;
         }

         
while(!empty(&A))
         
{
            
get(&A,&t1,&t2);
            
if(!used[t1][t2])
            
{
               used[t1][t2]
=1;
               xmin
=min(xmin,t1);
               xmax
=max(xmax,t1);
               ymin
=min(ymin,t2);
               ymax
=max(ymax,t2);
               
for(k=0;k<8;k++)
                 
if(t1+id[k]>=0&&t1+id[k]<r&&t2+jd[k]>=0&&t2+jd[k]<c&&!used[t1+id[k]][t2+jd[k]]&&map[t1+id[k]][t2+jd[k]]=='#')
                   put(
&A,t1+id[k],t2+jd[k]);
            }

         }

         
if(flag)
         
{
            re
+= (xmax-xmin+1)*(ymax-ymin+1);
            (
*ans)++;
         }

      }

    
return re;
}

int main()
{
    FILE 
*fin,*fout;
    fin
=fopen("battle.in","r");
    
long i,j,area1,area2,ans=0;
    fscanf(fin,
"%ld%ld",&r,&c);
    
for(i=0;i<r;i++)
      fscanf(fin,
"%s",map[i]);
    fclose(fin);
//------Read In
    area1=bfs1();
    area2
=bfs2(&ans);
    fout
=fopen("battle.out","w");
    
if(area1!=area2)
      fprintf(fout,
"Bad placement.\n");
    
else
      fprintf(fout,
"There are %ld ships.\n",ans);
    fclose(fout);
return 0;
}

posted on 2010-01-06 18:46 lee1r 阅读(361) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:搜索

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理