Weed (DFS)
来源:互联网 发布:淘宝沙河力度 编辑:程序博客网 时间:2024/05/16 12:47
Weed
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 41 Accepted Submission(s) : 13
.) denotes an empty square.
sample input
sample output
3 3 X.. .X. .X.
6
sample input
sample output
3 4 X..X .X.. .X..
12
题目大意:
有一片网格空地,有杂草,也有干净的土地。已知如果一个干净的土地四个方向的邻接土地有两个或者两个以上为杂草,那么它也会变成杂草。
给定一个地图,问一共会有多少块生长杂草的地面。
题目思路:
这道题目想了好久,虽然是简单的搜索。但是,奈何我还是不会,莫非还是没摸到搜索的窍门。但是还是要多做。
我一开始的思路是把全图遍历一边,用DFS,遇到是空地且周围有两个杂草地的,就计数一个,并把它变为杂草,对于,一开始我所占的土地是空地,但是因为下一个扩展点的地面变成杂草之后,我站的地面可以变为杂草,这样的情况我是利用DFS回溯的性质,把之前走过的再检查一遍。但是很可惜,TE了。估计还是我的方法不行,因为找不到什么别的剪枝的方法了,如果你能有新的剪枝方法,一定要私信我
代码如下:
#include<stdio.h>#include<string.h>bool vis[3000][3000];char map[3000][3000];int N,M;int count;int x_move[4] = {-1, 0, 1, 0};int y_move[4] = {0, 1, 0, -1};int is_ok(int x,int y){ int i; int sum=0; for(i=0;i<4;i++) if(map[x+x_move[i]][y+y_move[i]]=='X') sum++; return sum;}void DFS(int x,int y){ int i,j; int tx,ty; if(is_ok(x,y)>=2&&(x==1&&y==1)&&map[x][y]=='.') { map[x][y]='X'; count++; } for(i=0;i<4;i++) { tx=x+x_move[i]; ty=y+y_move[i]; if(tx<1||tx>N||ty<1||ty>M) continue; if(vis[tx][ty]==0) { vis[tx][ty]=1; if(is_ok(tx,ty)>=2&&map[tx][ty]=='.') { count++; map[tx][ty]='X'; } DFS(tx,ty); vis[tx][ty]=0; if(is_ok(tx,ty)>=2&&map[tx][ty]=='.') { count++; map[tx][ty]='X'; } } }}int main(){ int i,j; int a,b; while(scanf("%d%d",&N,&M)!=EOF) { getchar(); count=0; int flag=1; memset(vis,0,sizeof(vis)); for(i=1;i<=N;i++) { for(j=1;j<=M;j++) { scanf("%c",&map[i][j]); // if(map[i][j]=='.'&&flag==1){a=i;b=j;flag=0;vis[i][j]=1;} if(map[i][j]=='X')count++; } getchar(); } DFS(1,1); printf("%d\n",count); } return 0;}
后来更正思路,采取这样的做法,先遍历图一次,如果我碰到可以由空地变为杂草的点,把他变为杂草之后,那么我以这个点为起点进行搜索,如果他的四个方向中有空地可以变成杂草的话,那么继续搜索,这样做就是为了处理之前走过的土地一开始不能变为杂草,但是现在可以的情况。如果该地面不能变为杂草,那么回溯。
其实第一次遍历图的目的是计算,原图中可以变为杂草的点,DFS的作用就是,当增加新的杂草点的时候,进行扩展,看有没有因为新增加的杂草地面而有更多的,空地变为杂草
最后遍历图一次,找是X的点,计数输出。
代码如下:
#include<stdio.h>#include<string.h>bool vis[3000][3000];char map[3000][3000];int N,M;int count;int x_move[4] = {-1, 0, 1, 0};int y_move[4] = {0, 1, 0, -1};int is_ok(int x,int y){int i;int sum=0;if(map[x][y]=='X')return 0;for(i=0;i<4;i++){if(map[x+x_move[i]][y+y_move[i]]=='X')sum++;if(sum>=2)map[x][y]='X';}if(sum>=2)return 1;elsereturn 0;}void DFS(int x,int y){int i,j;int tx,ty;for(i=0;i<4;i++){tx=x+x_move[i];ty=y+y_move[i];if(tx<0||tx>=N||ty<0||ty>=M)continue;if(map[tx][ty]=='.'){if(is_ok(tx,ty))DFS(tx,ty);}}}int main(){int i,j;while(scanf("%d%d",&N,&M)!=EOF){count=0;for(i=0;i<N;i++)scanf("%s",map[i]);for(i=0;i<N;i++)for(j=0;j<M;j++)if(is_ok(i,j)) DFS(i,j);for(i=0;i<N;i++)for(j=0;j<M;j++)if(map[i][j]=='X')count++;printf("%d\n",count);}return 0;}
再次贴上一份队里面大神的代码,很简洁。值得学习,我的代码一直很烂:
#include<stdio.h>int n,m;char map[1001][1001];int dir[4][2]={0,1,0,-1,1,0,-1,0};int ok(int x,int y){ int i,cnt=0; if(map[x][y]=='X') return 0; for(i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(xx>=0&&x<n&&yy>=0&&yy<m) { if(map[xx][yy]=='X') cnt++; } } if(cnt>=2) {map[x][y]='X';return 1;} return 0;}void DFS(int x,int y){ int i; for(i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(xx>=0&&x<n&&yy>=0&&yy<m) { if(map[xx][yy]=='.') if(ok(xx,yy)) DFS(xx,yy); } }}int main(){ int i,j; while(scanf("%d %d",&n,&m)!=EOF) { for(i=0;i<n;i++) scanf("%s",map[i]); for(i=0;i<n;i++) for(j=0;j<m;j++) if(ok(i,j)) DFS(i,j); int ans=0; for(i=0;i<n;i++) for(j=0;j<m;j++) if(map[i][j]=='X') ans++; printf("%d\n",ans); } return 0;}
- Weed (DFS)
- Weed
- weed
- Java Weed
- SSU 334 Weed
- maven - Maven Weed
- weed-fs 源码解读
- 2.10. weed-fs
- (sgu-344)Weed
- weed-fs使用简介
- 线段树 weed
- Weed(BFS,好题)
- python-weed的seaweedfs使用指南
- 分布式存储Weed-FS源码分析
- weed-fs 源码解读—分布式处理过程
- DFS
- DFS
- dfs
- Ural 1517. Freedom of Choice 后缀数组
- 51下广告灯数码管和MSP430数码管
- linux下解压*.tar.xz文件
- POJ 1151: Atlantis
- c语言字符格式
- Weed (DFS)
- MySql支持的运算符
- 51/MSP430数码管的拉幕式效果
- java几种读取.properties文件的方法
- How to think like a computer scientist: 第四章 课后习题 1
- iOS ——— static
- Mysql最基本、最常用命令集锦
- Qt hello
- 黑马程序员_面向对象3_(异常Exception、包package、String类、StringBuffer类)