openjudge-最好的草

http://noi.openjudge.cn/ch0108/17/

总时间限制: 10000ms   单个测试点时间限制: 1000ms  内存限制: 65536kB
描述

奶牛Bessie计划好好享受柔软的春季新草。新草分布在R行C列的牧场里。它想计算一下牧场中的草丛数量。

在牧场地图中,每个草丛要么是单个“#”,要么是有公共边的相邻两个“#”。给定牧场地图,计算有多少个草丛。

例如,考虑如下5行6列的牧场地图

.#....
..#...
..#..#
...##.
.#....

这个牧场有5个草丛:一个在第一行,一个在第二列横跨了二、三行,一个在第三行,一个在第四行横跨了四、五列,最后一个在第五行。

 

输入
第一行包含两个整数R和C,中间用单个空格隔开。
接下来R行,每行C个字符,描述牧场地图。字符只有“#”或“.”两种。
输出
输出一个整数,表示草丛数。
样例输入
5 6
.#....
..#...
..#..#
...##.
.#....
样例输出
5
来源
USACO Open 2008 Bronze

解析:

广搜。具体步骤就是扫描二维数组,发现'#'号则从该坐标出发进行广搜,搜索的同时把搜过的'#'号修改为'.'   。

 1 #include <stdio.h>
 2 int count=0,R,C;
 3 void bfs(char a[105][105],int i,int j);//从a[i][j]出发做bfs 
 4 int main(int argc, char *argv[])
 5 {
 6     int i,j;
 7     char a[105][105];
 8     //freopen("17.in","r",stdin);
 9     //freopen("17.txt","w",stdout);
10     scanf("%d%d",&R,&C);
11     for(i=0;i<R;i++) scanf("%s",a[i]);
12     
13     for(i=0;i<R;i++)
14     {
15         for(j=0;j<C;j++)
16         {
17             if(a[i][j]=='#') bfs(a,i,j);
18         }
19     }
20     printf("%d\n",count);
21     return 0;
22 }
23 void bfs(char a[105][105],int i,int j)
24 {
25     int queueArr[10010][2];
26     int begin,end,number;//队头,队尾,队列元素数目 
27     int x,y,xx,yy;
28     
29     count++;//草块数目增加1 
30     
31     a[i][j]='.';
32     queueArr[0][0]=i;
33     queueArr[0][1]=j;
34     begin=0;
35     end=1;
36     number=1;
37     
38     while(number>0)//当队列不为空时继续循环
39     {
40         //读取队头元素的值 
41         x=queueArr[begin][0];
42         y=queueArr[begin][1];
43         
44         //查询队头元素的周围节点是否'#' 
45         xx=x;
46         yy=y-1;
47         if(yy>=0&&a[xx][yy]=='#')
48         {
49             a[xx][yy]='.';
50             queueArr[end][0]=xx;
51             queueArr[end][1]=yy;
52             end++;
53             number++;
54         }
55         
56         xx=x;
57         yy=y+1;
58         if(yy<C&&a[xx][yy]=='#')
59         {
60             a[xx][yy]='.';
61             queueArr[end][0]=xx;
62             queueArr[end][1]=yy;
63             end++;
64             number++;
65         }
66         
67         xx=x-1;
68         yy=y;
69         if(xx>=0&&a[xx][yy]=='#')
70         {
71             a[xx][yy]='.';
72             queueArr[end][0]=xx;
73             queueArr[end][1]=yy;
74             end++;
75             number++;
76         }
77         
78         xx=x+1;
79         yy=y;
80         if(xx<R&&a[xx][yy]=='#')
81         {
82             a[xx][yy]='.';
83             queueArr[end][0]=xx;
84             queueArr[end][1]=yy;
85             end++;
86             number++;
87         }
88         
89         begin++;//队头出队 
90         number--;//队列元素数目减少1个 
91     }
92 }

 深搜代码:

 1 #include <stdio.h>
 2 int count=0,R,C;
 3 char a[105][105];
 4 int dx[4]={-1,1,0,0};//上下左右 
 5 int dy[4]={0,0,-1,1};
 6 void dfs(int i,int j);//从a[i][j]出发做bfs 
 7 int main(int argc, char *argv[])
 8 {
 9     int i,j;
10     
11     freopen("1.in","r",stdin);
12     //freopen("1.txt","w",stdout);
13     scanf("%d%d",&R,&C);
14     for(i=0;i<R;i++) scanf("%s",a[i]);
15     
16     for(i=0;i<R;i++)
17     {
18         for(j=0;j<C;j++)
19         {
20             if(a[i][j]=='#') { count++; dfs(i,j); }
21         }
22     }
23     printf("%d\n",count);
24     return 0;
25 }
26 void dfs(int i,int j)//从a[i][j]出发做dfs 
27 {
28     int xx,yy;
29     a[i][j]='.';
30     for(int k=0;k<4;k++)
31     {
32         xx=dx[k]+i;  yy=j+dy[k];
33         if(xx>=0&&xx<R&&yy>=0&&yy<C&&a[xx][yy]=='#') dfs(xx,yy);
34     }
35 }
View Code

 

简化的广搜代码

 1 #include <stdio.h>
 2 int count=0,R,C;
 3 int dx[4]={-1,1,0,0};//上下左右 
 4 int dy[4]={0,0,-1,1};
 5 void bfs(char a[105][105],int i,int j);//从a[i][j]出发做bfs 
 6 int main(int argc, char *argv[])
 7 {
 8     int i,j;
 9     char a[105][105];
10     freopen("1.in","r",stdin);
11     //freopen("1.txt","w",stdout);
12     scanf("%d%d",&R,&C);
13     for(i=0;i<R;i++) scanf("%s",a[i]);
14     
15     for(i=0;i<R;i++)
16     {
17         for(j=0;j<C;j++)
18         {
19             if(a[i][j]=='#') bfs(a,i,j);
20         }
21     }
22     printf("%d\n",count);
23     return 0;
24 }
25 void bfs(char a[105][105],int i,int j)
26 {
27     int queueArr[10010][2];
28     int begin,end,number;//队头,队尾,队列元素数目 
29     int x,y,xx,yy;
30     
31     count++;//草块数目增加1 
32     
33     a[i][j]='.';
34     queueArr[0][0]=i;
35     queueArr[0][1]=j;
36     begin=0;
37     end=1;
38     number=1;
39     
40     while(number>0)//当队列不为空时继续循环
41     {
42         //读取队头元素的值 
43         x=queueArr[begin][0];
44         y=queueArr[begin][1];
45         //查询队头元素的周围节点是否'#' 
46         for(int k=0;k<4;k++)
47         {
48             xx=dx[k]+x; yy=dy[k]+y;
49             if(xx>=0&&xx<R&&yy>=0&&yy<C&&a[xx][yy]=='#')
50             {
51                 a[xx][yy]='.';
52                 queueArr[end][0]=xx;
53                 queueArr[end][1]=yy;
54                 end++;
55                 number++;
56             }
57         }
58         begin++;//队头出队 
59         number--;//队列元素数目减少1个 
60     }
61 }
View Code

 

使用STL队列的广搜:

 

 1 #include<stdio.h>
 2 #include<queue>
 3 using namespace std;
 4 
 5 struct obj
 6 {
 7     int x,y;
 8 };
 9 
10 int count=0,R,C;
11 int dx[4]={-1,1,0,0};//上下左右 
12 int dy[4]={0,0,-1,1};
13 
14 void bfs(char a[105][105],int i,int j);//从a[i][j]出发做bfs 
15 int main(int argc, char *argv[])
16 {
17     int i,j;
18     char a[105][105];
19     freopen("1.in","r",stdin);
20     //freopen("1.txt","w",stdout);
21     scanf("%d%d",&R,&C);
22     for(i=0;i<R;i++) scanf("%s",a[i]);
23     
24     for(i=0;i<R;i++)
25     {
26         for(j=0;j<C;j++)
27         {
28             if(a[i][j]=='#') bfs(a,i,j);
29         }
30     }
31     printf("%d\n",count);
32     return 0;
33 }
34 void bfs(char a[105][105],int i,int j)
35 {
36     int xx,yy;
37     queue<struct obj> queA;
38     struct obj temp;
39     
40     count++;//草块数目增加1 
41 
42     a[i][j]='.';//访问当前出发点 
43     temp.x=i;
44     temp.y=j;
45     queA.push(temp);//出发点入队 
46 
47     while(!queA.empty())//当队列不为空时继续循环
48     {
49         //查询队头元素的周围节点是否'#' 
50         for(int k=0;k<4;k++)
51         {
52             xx=dx[k]+queA.front().x;
53             yy=dy[k]+queA.front().y;
54             if(xx>=0&&xx<R&&yy>=0&&yy<C&&a[xx][yy]=='#')
55             {
56                 a[xx][yy]='.';
57                 struct obj t;
58                 t.x=xx;
59                 t.y=yy;
60                 queA.push(t);
61             }
62         }
63         queA.pop();//删除队头 
64     }
65 }
View Code

 

 

下面同样是使用了STL队列的广搜,不过在结构体定义时使用了结构体构造函数,可以看看:

 

 1 #include<stdio.h>
 2 #include<queue>
 3 using namespace std;
 4 
 5 struct obj
 6 {
 7     int x,y;
 8     obj(int xx,int yy){ x=xx;y=yy; }
 9     obj(){ x=0;y=0; }
10 };
11 
12 int count=0,R,C;
13 int dx[4]={-1,1,0,0};//上下左右 
14 int dy[4]={0,0,-1,1};
15 
16 void bfs(char a[105][105],int i,int j);//从a[i][j]出发做bfs 
17 int main(int argc, char *argv[])
18 {
19     int i,j;
20     char a[105][105];
21     freopen("1.in","r",stdin);
22     //freopen("1.txt","w",stdout);
23     scanf("%d%d",&R,&C);
24     for(i=0;i<R;i++) scanf("%s",a[i]);
25     
26     for(i=0;i<R;i++)
27     {
28         for(j=0;j<C;j++)
29         {
30             if(a[i][j]=='#') bfs(a,i,j);
31         }
32     }
33     printf("%d\n",count);
34     return 0;
35 }
36 void bfs(char a[105][105],int i,int j)
37 {
38     int xx,yy;
39     queue<struct obj> queA;
40     struct obj temp;
41     
42     count++;//草块数目增加1 
43 
44     a[i][j]='.';//访问当前出发点 
45     //temp.x=i;
46     //temp.y=j;
47     //queA.push(temp);//出发点入队 
48     queA.push(obj(i,j));
49 
50     while(!queA.empty())//当队列不为空时继续循环
51     {
52         //查询队头元素的周围节点是否'#' 
53         for(int k=0;k<4;k++)
54         {
55             xx=dx[k]+queA.front().x;
56             yy=dy[k]+queA.front().y;
57             if(xx>=0&&xx<R&&yy>=0&&yy<C&&a[xx][yy]=='#')
58             {
59                 a[xx][yy]='.';
60                 //struct obj t;
61                 //t.x=xx;
62                 //t.y=yy;
63                 //queA.push(t);
64                 queA.push(obj(xx,yy));
65             }
66         }
67         queA.pop();//删除队头 
68     }
69 }
View Code

 

转载于:https://www.cnblogs.com/huashanqingzhu/p/5663386.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值