HDU--OJ--1241 Oil Deposits

点击打开链接




Oil Deposits

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3427    Accepted Submission(s): 1954


Problem Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
 

Input
The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
 

Output
For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.

Sample Input
  
  
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
 

Sample Output
  
  
0 1 2 2



题解:


有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索。它们最终都会到达所有连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。  

深度优先搜索:
下面图中的数字显示了深度优先搜索顶点被访问的顺序。

为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
(1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
(2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
(3) 如果不能执行规则1和规则2,就完成了整个搜索过程。

广度优先搜索:
在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区域。它是用队列来实现的。
下面图中的数字显示了广度优先搜索顶点被访问的顺序。

实现广度优先搜索,也要遵守三个规则:
(1) 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
(2) 如果因为已经没有未访问顶点而不能执行规则1时,那么从队列头取一个顶点,并使其成为当前顶点。
(3) 如果因为队列为空而不能执行规则2,则搜索结束。


AC代码:


DFS:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e2 + 10;
typedef long long LL;
char s[MAX][MAX];
int n,m,vis[MAX][MAX],ans;
int fx[8] = {0,0,-1,1,-1,1,-1,1},fy[8] = {-1,1,0,0,-1,-1,1,1}; // 8 个方向 
void dfs(int x,int y){
    vis[x][y] = 1;
    for(int i = 0; i < 8; i++){
        int xx = x + fx[i],yy  = fy[i] + y;
        if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@') // 判断是否出界, 是否已经搜索过, 是否为油田 
            dfs(xx,yy);
    }
}
int main()
{
    while(~scanf("%d %d",&n,&m),m){
        memset(vis,0,sizeof(vis));
        for(int i = 0; i < n; i++)
            scanf("%s",s[i]);
        ans = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                if(!vis[i][j] && s[i][j] == '@')
                    ans++,dfs(i,j); // 第一次搜到 + 1 
        printf("%d\n",ans);
    }
    return 0;
}



BFS:

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e2 + 10;
typedef long long LL;
char s[MAX][MAX];
int n,m,vis[MAX][MAX],ans;
int fx[8] = {0,0,-1,1,-1,1,-1,1},fy[8] = {-1,1,0,0,-1,-1,1,1};
struct node{
    int x,y;
};
void bfs(int x,int y){
    vis[x][y] = 1;
    queue <node> q;
    node o;
    o.x = x,o.y = y;
    q.push(o);
    while(!q.empty()){
        o = q.front();
        q.pop();
        for(int i = 0; i < 8; i++){ // 8 个方向  
            int xx = o.x + fx[i],yy = o.y + fy[i];
            if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@'){  // 判断是否出界, 是否已经搜索过, 是否为油田 
                node w;
                vis[xx][yy] = 1;
                w.x = xx,w.y = yy;
                q.push(w);
            }
        }
    }
}
int main()
{
    while(~scanf("%d %d",&n,&m),m){
        memset(vis,0,sizeof(vis));
        for(int i = 0; i < n; i++)
            scanf("%s",s[i]);
        ans = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                if(!vis[i][j] && s[i][j] == '@')
                    ans++,bfs(i,j); // // 第一次搜到 + 1  
        printf("%d\n",ans);
    }
    return 0;
}






内容概要:本文详细介绍了水中有限长加肋圆柱壳体振动和声辐射的近似解析解,并提供了完整的Python实现。文中首先阐述了问题背景,即加肋圆柱壳体作为水下航行器的主要结构形式,肋骨的作用被简化为只有法向力。接着,通过一系列关键方程(如模态振动速度方程、壳体机械阻抗、特征矩阵元素等),推导出加肋圆柱壳体的振动和声辐射特性。Python代码部分实现了这些理论,包括定义`CylindricalShell`类来封装所有计算功能,如初始化参数、机械阻抗、辐射阻抗、肋骨阻抗、模态速度、辐射功率和辐射效率的计算。此外,还扩展了带刚性圆柱障板的圆柱壳体类`CylindricalShellWithBaffle`,并引入了集中力激励、简支边界条件和低频段计算的内容。最后,通过具体示例展示了如何创建壳体对象、设置参数、计算频率响应以及绘制结果图表,验证了加肋对辐射声功率和声辐射效率的影响。 适合人群:具备一定编程基础和声学基础知识的研究人员、工程师,特别是从事水下声学、船舶工程和振动分析领域的专业人员。 使用场景及目标:①通过代码实现和理论推导,深入理解加肋圆柱壳体的振动和声辐射特性;②分析肋骨对壳体声学性能的影响,优化结构设计;③利用Python代码进行数值模拟,评估不同参数配置下的声辐射效率和功率;④为实际工程项目提供理论支持和技术参考。 其他说明:本文不仅提供了详细的数学推导和Python代码实现,还讨论了实际应用中的注意事项,如参数调整、高频模态考虑、肋骨模型细化和数值稳定性处理。建议读者结合实际需求,灵活运用文中提供的理论和代码,进行更深入的研究和实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值