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

解析:

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

 #include <stdio.h>
int count=,R,C;
void bfs(char a[][],int i,int j);//从a[i][j]出发做bfs
int main(int argc, char *argv[])
{
int i,j;
char a[][];
//freopen("17.in","r",stdin);
//freopen("17.txt","w",stdout);
scanf("%d%d",&R,&C);
for(i=;i<R;i++) scanf("%s",a[i]); for(i=;i<R;i++)
{
for(j=;j<C;j++)
{
if(a[i][j]=='#') bfs(a,i,j);
}
}
printf("%d\n",count);
return ;
}
void bfs(char a[][],int i,int j)
{
int queueArr[][];
int begin,end,number;//队头,队尾,队列元素数目
int x,y,xx,yy; count++;//草块数目增加1 a[i][j]='.';
queueArr[][]=i;
queueArr[][]=j;
begin=;
end=;
number=; while(number>)//当队列不为空时继续循环
{
//读取队头元素的值
x=queueArr[begin][];
y=queueArr[begin][]; //查询队头元素的周围节点是否'#'
xx=x;
yy=y-;
if(yy>=&&a[xx][yy]=='#')
{
a[xx][yy]='.';
queueArr[end][]=xx;
queueArr[end][]=yy;
end++;
number++;
} xx=x;
yy=y+;
if(yy<C&&a[xx][yy]=='#')
{
a[xx][yy]='.';
queueArr[end][]=xx;
queueArr[end][]=yy;
end++;
number++;
} xx=x-;
yy=y;
if(xx>=&&a[xx][yy]=='#')
{
a[xx][yy]='.';
queueArr[end][]=xx;
queueArr[end][]=yy;
end++;
number++;
} xx=x+;
yy=y;
if(xx<R&&a[xx][yy]=='#')
{
a[xx][yy]='.';
queueArr[end][]=xx;
queueArr[end][]=yy;
end++;
number++;
} begin++;//队头出队
number--;//队列元素数目减少1个
}
}

深搜代码:

 #include <stdio.h>
int count=,R,C;
char a[][];
int dx[]={-,,,};//上下左右
int dy[]={,,-,};
void dfs(int i,int j);//从a[i][j]出发做bfs
int main(int argc, char *argv[])
{
int i,j; freopen("1.in","r",stdin);
//freopen("1.txt","w",stdout);
scanf("%d%d",&R,&C);
for(i=;i<R;i++) scanf("%s",a[i]); for(i=;i<R;i++)
{
for(j=;j<C;j++)
{
if(a[i][j]=='#') { count++; dfs(i,j); }
}
}
printf("%d\n",count);
return ;
}
void dfs(int i,int j)//从a[i][j]出发做dfs
{
int xx,yy;
a[i][j]='.';
for(int k=;k<;k++)
{
xx=dx[k]+i; yy=j+dy[k];
if(xx>=&&xx<R&&yy>=&&yy<C&&a[xx][yy]=='#') dfs(xx,yy);
}
}

简化的广搜代码

 #include <stdio.h>
int count=,R,C;
int dx[]={-,,,};//上下左右
int dy[]={,,-,};
void bfs(char a[][],int i,int j);//从a[i][j]出发做bfs
int main(int argc, char *argv[])
{
int i,j;
char a[][];
freopen("1.in","r",stdin);
//freopen("1.txt","w",stdout);
scanf("%d%d",&R,&C);
for(i=;i<R;i++) scanf("%s",a[i]); for(i=;i<R;i++)
{
for(j=;j<C;j++)
{
if(a[i][j]=='#') bfs(a,i,j);
}
}
printf("%d\n",count);
return ;
}
void bfs(char a[][],int i,int j)
{
int queueArr[][];
int begin,end,number;//队头,队尾,队列元素数目
int x,y,xx,yy; count++;//草块数目增加1 a[i][j]='.';
queueArr[][]=i;
queueArr[][]=j;
begin=;
end=;
number=; while(number>)//当队列不为空时继续循环
{
//读取队头元素的值
x=queueArr[begin][];
y=queueArr[begin][];
//查询队头元素的周围节点是否'#'
for(int k=;k<;k++)
{
xx=dx[k]+x; yy=dy[k]+y;
if(xx>=&&xx<R&&yy>=&&yy<C&&a[xx][yy]=='#')
{
a[xx][yy]='.';
queueArr[end][]=xx;
queueArr[end][]=yy;
end++;
number++;
}
}
begin++;//队头出队
number--;//队列元素数目减少1个
}
}

使用STL队列的广搜:

 #include<stdio.h>
#include<queue>
using namespace std; struct obj
{
int x,y;
}; int count=,R,C;
int dx[]={-,,,};//上下左右
int dy[]={,,-,}; void bfs(char a[][],int i,int j);//从a[i][j]出发做bfs
int main(int argc, char *argv[])
{
int i,j;
char a[][];
freopen("1.in","r",stdin);
//freopen("1.txt","w",stdout);
scanf("%d%d",&R,&C);
for(i=;i<R;i++) scanf("%s",a[i]); for(i=;i<R;i++)
{
for(j=;j<C;j++)
{
if(a[i][j]=='#') bfs(a,i,j);
}
}
printf("%d\n",count);
return ;
}
void bfs(char a[][],int i,int j)
{
int xx,yy;
queue<struct obj> queA;
struct obj temp; count++;//草块数目增加1 a[i][j]='.';//访问当前出发点
temp.x=i;
temp.y=j;
queA.push(temp);//出发点入队 while(!queA.empty())//当队列不为空时继续循环
{
//查询队头元素的周围节点是否'#'
for(int k=;k<;k++)
{
xx=dx[k]+queA.front().x;
yy=dy[k]+queA.front().y;
if(xx>=&&xx<R&&yy>=&&yy<C&&a[xx][yy]=='#')
{
a[xx][yy]='.';
struct obj t;
t.x=xx;
t.y=yy;
queA.push(t);
}
}
queA.pop();//删除队头
}
}

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

 #include<stdio.h>
#include<queue>
using namespace std; struct obj
{
int x,y;
obj(int xx,int yy){ x=xx;y=yy; }
obj(){ x=;y=; }
}; int count=,R,C;
int dx[]={-,,,};//上下左右
int dy[]={,,-,}; void bfs(char a[][],int i,int j);//从a[i][j]出发做bfs
int main(int argc, char *argv[])
{
int i,j;
char a[][];
freopen("1.in","r",stdin);
//freopen("1.txt","w",stdout);
scanf("%d%d",&R,&C);
for(i=;i<R;i++) scanf("%s",a[i]); for(i=;i<R;i++)
{
for(j=;j<C;j++)
{
if(a[i][j]=='#') bfs(a,i,j);
}
}
printf("%d\n",count);
return ;
}
void bfs(char a[][],int i,int j)
{
int xx,yy;
queue<struct obj> queA;
struct obj temp; count++;//草块数目增加1 a[i][j]='.';//访问当前出发点
//temp.x=i;
//temp.y=j;
//queA.push(temp);//出发点入队
queA.push(obj(i,j)); while(!queA.empty())//当队列不为空时继续循环
{
//查询队头元素的周围节点是否'#'
for(int k=;k<;k++)
{
xx=dx[k]+queA.front().x;
yy=dy[k]+queA.front().y;
if(xx>=&&xx<R&&yy>=&&yy<C&&a[xx][yy]=='#')
{
a[xx][yy]='.';
//struct obj t;
//t.x=xx;
//t.y=yy;
//queA.push(t);
queA.push(obj(xx,yy));
}
}
queA.pop();//删除队头
}
}

openjudge-最好的草的更多相关文章

  1. 【OpenJudge 8463】Stupid cat & Doge

    http://noi.openjudge.cn/ch0204/8463/ 挺恶心的一道简单分治. 一开始准备非递归. 大if判断,后来发现代码量过长,决定大打表判断后继情况,后来发现序号不对称. 最后 ...

  2. 【OpenJudge 191】【POJ 1189】钉子和小球

    http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...

  3. 【OpenJudge 1665】完美覆盖

    http://noi.openjudge.cn/ch0405/1665/?lang=zh_CN 状压水题,手动转移 #include<cstdio> #include<cstring ...

  4. 【OpenJudge 1793】矩形覆盖

    http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...

  5. OpenJudge 2990:符号三角形 解析报告

    2990:符号三角形 总时间限制:  1000ms       内存限制:  65536kB 描述 符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“ ...

  6. codevs 2801 LOL-盖伦的蹲草计划

     时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题目描述 Description 众所周知,LOL这款伟大的游戏,有个叫盖伦的英雄.他的伟大之处在于他特别喜欢蹲 ...

  7. noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20

    T11 图像旋转 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数.1 <= n <= 100,1 <= ...

  8. OpenJudge解题经验交流

    1.1编程基础之输入输出01:Hello, World! 02:输出第二个整数PS:a,b需用longint类型接收 03:对齐输出 04:输出保留3位小数的浮点数 05:输出保留12位小数的浮点数 ...

  9. Unity3D手游开发日记(9) - 互动草的效果

    所谓互动草,就是角色跑动或者释放技能,能影响草的摆动方向和幅度. 前面的文章早已经实现了风吹草动的效果,迟迟没有在Unity上面做互动草,是因为以前我在端游项目做过一套太过于牛逼的方案.在CE3的互动 ...

随机推荐

  1. QImage::drawRect 和 fillRect在处理大面积区域时代价高昂

    项目需要生成一张掩码图, 出于操作pixel方便的考虑采用QImage(mono), 但在实现一个类似于 cvZero的操作时发现在图片面积较大时效率很低, 提醒一下 ps: 后来是改变策略, 用偏移 ...

  2. android 帧动画的实现及图片过多时OOM解决方案(一)

    一,animation_list.xml中静态配置帧动画的顺序,如下: <?xml version="1.0" encoding="utf-8"?> ...

  3. 【zz】matlab 腐蚀膨胀算法

    1.图像膨胀的Matlab实现: 可以使用imdilate函数进行图像膨胀,imdilate函数需要两个基本输入参数,即待处理的输入图像和结构元素对象.结构元素对象可以是strel函数返回的对象,也可 ...

  4. 用tcpdump分析tcp三次握手,四次挥手

    1.tcpdump 简介 tcpdump是一个对网络上的数据包进行截获的包分析工具,一般linux系统以命令的形式使用 2.tcp三次握手 建立一个tcp连接会发生下面三个过程: 1.服务器必须准备好 ...

  5. Unity3D中可中途释放的单例

    Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...

  6. 锤子手机T2 屏幕录像文件保存在哪里?

    在根目录下的 /Video/ScreenRecorder 下面   转至: http://30daydo.com/article/115

  7. 新建jfinal2.2项目并连接mysql

    一新建项目 1. new→Dynamic  Web Project 2修改Default Output Folder.一般用WebRoot\WEB-INF\class,然后下一步(注意路径要写对,不然 ...

  8. Unity使用protobuf-net进行二进制序列化与反序列化

    Protobuf-net提供的一种易于使用的数据序列化方案,可序列化带有[ProtoContract]特性的类实例,并可支持Unity各个发布平台,且效率高.易用性强. public static c ...

  9. Photoshop制作的海报修改~

    经过几天的征求意见,感觉还是要重新制作,于是把颜色删减了不少 . 这次运用了蒙版和渐变,但感觉效果不太好.再改.. 后来觉得给人的单身感有点少.. 不知道感觉如何,但自己觉得比以前好看..

  10. easyui 筛选数据及仅允许选择数据

    先说需求,本地已缓存数据源,用户输入拼音码或编号,筛选数据作为新的数据源,然后通过键盘选择. 再说问题,easyui combogrid控件,在mode为local,也就是将数据源缓存在本地的情况下, ...