Oil Deposits poj-1562
题目大意:给你一个字符串方阵,由‘@‘和‘*‘组成。@表示油田,一个油田的周围8个方向如果有@则说这两个油田是一个油田,求整个方阵里油田的个数。
注释:方阵的长和宽都是两位数。
想法:挺水的一道题,显然的爆搜,我们用两种方法来搜。
1.从第一个开始从左往右直接搜,用answer[i][j]表示i,j这个位置如果是油田的话是第几个油田。然后记录一个全局变量ans表示当前油田数。如果当前这个油田的上面三个方向和左面都有任意一个数油田,去任意一个即可。因为如果后面的油田与当前这个油田联通,那么我们及时把那个油田和当前油田赋值成当前油田的油田数,也是无所谓的。如果那四个方向都不与当前油田联通,我们就将它赋值成ans+1,ans++。
2.从不同的油田开始搜。在主函数里决定是否对当前的字符进行搜索。搜索的方式是从一个点向周围8个方向进行枚举,枚举过的就用bool变量visit[i][j]记录。最后,统计进入了总共进入了多少次就行了。即在主函数里有多少个油田作为搜索的第一层。
我附上的是第二种方法的代码。两种方法没有任何差异性。如果方阵的长和宽分别为n和m的话,因为每个点被搜过且仅被搜过一次,所以时间复杂度是O(n*m)。
最后,附上丑陋的代码... ...
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define MAX 101 5 using namespace std; 6 int n,m,ans; 7 char map[MAX][MAX]; 8 bool vis[MAX][MAX]; 9 int movex[8]={1,1,1,-1,-1,-1,0,0}; 10 int movey[8]={1,0,-1,1,0,-1,1,-1}; 11 bool isborder(int x,int y) 12 { 13 if(x<0||x>=n||y<0||y>=m) 14 return true; 15 return false; 16 } 17 void DFS(int x,int y) 18 { 19 if(isborder(x,y)||map[x][y]==‘*‘) 20 return; 21 for(int i=0;i<8;i++) 22 { 23 int itx=x+movex[i]; 24 int ity=y+movey[i]; 25 if(isborder(itx,ity)||vis[itx][ity]) 26 continue; 27 vis[itx][ity]=1; 28 if(map[itx][ity]==‘@‘) 29 DFS(itx,ity); 30 } 31 } 32 int main() 33 { 34 while(scanf("%d%d",&n,&m)&&(n||m)) 35 { 36 for(int i=0;i<n;i++) 37 scanf("%s",&map[i]); 38 memset(vis,0,sizeof(vis)); 39 ans=0; 40 for(int i=0;i<n;i++) 41 for(int j=0;j<m;j++) 42 if(!vis[i][j]&&map[i][j]!=‘*‘) 43 { 44 DFS(i,j); 45 ans++; 46 } 47 printf("%d\n",ans); 48 } 49 return 0; 50 }
小结:没有什么技术含量,但是小题大做好像是一本练习册的名字... ...