问题:
这是一个面试问题。
一群农民有一些海拔数据,我们将帮助他们了解降雨如何流过他们的农田。
我们将土地表示为一个二维的高度数组,并根据水流下坡的想法使用以下模型:
如果一个单元格的八个相邻单元格都具有较高的海拔高度,我们称这个单元格为盆地;水聚集在盆中。
否则,水会流向海拔最低的相邻单元格。
直接或间接排入同一个汇的细胞被称为同一个盆地的一部分。
下面是几个例子:
输入:
1 1 2
1 1 7
3 6 9
尺寸 4
9 9 9 8 7 7
8 8 7 7 7 8
8 8 8 7 7 7
8 8 8 9 9 9
8 8 8 7 7 7
4 4 5 5 5 5
5 5 5 6 6 7
5 5 5 8 8 6
尺寸 8
9 9 9 8 8 8
8 8 8 7 7 7
7 7 7 7 7 7
8 8 8 8 9 9
5 5 5 5 6 3
5 5 5 3 3 3
9号
突出显示的值构成了最大尺寸的盆地。
所以问题是
将 map 划分为盆地。特别是,给定一张海拔图,您的代码应该将 map 划分为盆地并输出最大盆地的大小。 我们需要突出显示最大尺寸的盆地。
如果问题有这个假设
“如果一个单元格不是汇点,您可以假设它有一个唯一的最低邻居,并且这个邻居将低于该单元格”
然后我可以想到这个解决方案
Each array element is a node in a graph. Construct the graph adding edges between the nodes:
1 If node A is the smallest among all of its own neighbors, don't add an edge (it's a sink)
2 There is an edge between two neighbors A and B iff A is the smallest of all neighbors of B.
3 Finally traverse the graph using BFS or DFS and count the elements in the connected components.
到目前为止我已经实现了算法的第三部分
#include<iostream>
#include<vector>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int cv[1000]; // array stores number of nodes in each connected components
int main()
{
queue<int>q;
bool visited[100000];
int t,i,j,x,y,cvindex=0;
int n,e;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&e);
vector< vector<int> >G(n);
memset(visited,0,sizeof(visited));
for(i=0;i<e;i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
int ans=0;
for(i=0;i<n;i++)
{
if(!visited[i])
{
q.push(i);
visited[i]=1;
cv[cvindex]++;
while(!q.empty())
{
int p=q.front();
q.pop();
for(j=0;j<G[p].size();j++)
{
if(!visited[G[p][j]])
{
visited[G[p][j]]=1;
q.push(G[p][j]);
cv[cvindex]++;
}
}
}
ans++;
cvindex++;
}
}
printf("%d\n",ans);
sort(cv,cv+cvindex);
for(int zz=0;zz<cvindex;zz++)
printf("%d ",cv[zz]);
}
}
时间复杂度O(n*m)
但是如何在没有假设的情况下解决上述问题呢? 我想要几乎相似的方法,稍作修改。
欢迎使用其他算法。
而且在时间复杂度方面有没有更好的算法?
最佳答案
这是我的工作代码。为了您的理解,我还评论了我的每一步。如果您仍然找到一些帮助,您可以寻求帮助。
算法
时间复杂度:O(ROWS*COLUMNS)
#include<iostream>
#include<vector>
#include<string.h>
#include<climits>
#define BASIN 1
#define NOT_BASIN 2
#define NOT_DEFINED_YET 3
#define ROW 1000
#define COLUMN 1000
#define MAXIMUM_HEIGHT_POSSIBLE 1000
using namespace std;
int heights[ROW][COLUMN]; // It stores the height
int maximumBasin[ROW][COLUMN]; // It stores the state of each index, Total 3 states possible, ( BASIN, NOT_BASIN, NOT_DEFINED_YET )
bool alreadyVisited[ROW][COLUMN]; // True, if currect index visited, otherwise false.
vector< pair<int, int> > heightsCoordinates[MAXIMUM_HEIGHT_POSSIBLE]; // It stores all the indexs of given height.
int N, M, maxHeightPossible;
int dx[] = {0, 1, 1, 1, 0, -1, -1, -1};
int dy[] = {1, 1, 0, -1, -1, -1, 0, 1};
bool isValidLocation(int x, int y) {
if(x < 0 || x > M || y < 0 || y > N || alreadyVisited[x][y] == true) return false;
return true;
}
void DFS_FOR_MARKING_WITH_GIVEN_VALUE(int value, int x, int y) {
maximumBasin[x][y] = value;
alreadyVisited[x][y] = true;
for(int i = 0; i < 8; i++) if( isValidLocation(x + dx[i], y + dy[i]) && heights[x + dx[i]][y + dy[i]] >= heights[x][y] ) DFS_FOR_MARKING_WITH_GIVEN_VALUE(value, x + dx[i], y + dy[i]);
}
void DFS_FOR_COUNTING_BASINS_TOGETHER(int &cnt, int x, int y) {
cnt++;
alreadyVisited[x][y] = true;
for(int i = 0; i < 8; i++) if( isValidLocation(x+dx[i], y+dy[i]) && maximumBasin[x + dx[i]][y + dy[i]] == BASIN ) DFS_FOR_COUNTING_BASINS_TOGETHER(cnt, x + dx[i], y + dy[i]);
}
void printBasin() {
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) cout << maximumBasin[i][j] << " ";
cout << endl;
}
}
main() {
cin >> M >> N >> maxHeightPossible;
int x, y;
int maximumCounts = INT_MIN;
int cntTemp = 0;
/**
Take input and set NOT_DEFINED_YET for maximumBasin.
**/
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
cin >> heights[i][j];
maximumBasin[i][j] = NOT_DEFINED_YET;
heightsCoordinates[ heights[i][j] ].push_back(pair<int, int>(i, j));
}
}
/**
Iterate from smallest to largest height.
If current index is "NOT_DEFINED_YET" (means it is the candidate index where water can collect). Water will come here from all neighbourhood whose height is greater than this.
For that I call DFS_FOR_MARKING_WITH_GIVEN_VALUE function.
**/
for( int i = 0; i <= maxHeightPossible; i++ ){
if(heightsCoordinates[i].size() == 0) continue;
for(int j = 0; j < heightsCoordinates[i].size(); j++) {
x = heightsCoordinates[i][j].first;
y = heightsCoordinates[i][j].second;
if( maximumBasin[x][y] == NOT_DEFINED_YET ) {
maximumBasin[x][y] = BASIN;
alreadyVisited[x][y] = true;
for(int k = 0; k < 8; k++) {
if( isValidLocation( x + dx[k], y + dy[k] ) ) {
if ( heights[x + dx[k]][ y + dy[k]] > heights[x][y] ) {
DFS_FOR_MARKING_WITH_GIVEN_VALUE(NOT_BASIN, x + dx[k], y + dy[k]);
}
}
}
}
else {
// If it is set by BASIN or NOT_BASIN, Shows already processed before.
}
}
}
//printBasin();
memset(alreadyVisited, 0, sizeof(alreadyVisited));
/**
It simply counts basins which are together.
**/
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
if( alreadyVisited[i][j] == false && maximumBasin[i][j] == BASIN) {
DFS_FOR_COUNTING_BASINS_TOGETHER(cntTemp, i, j);
//cout << cntTemp << endl;
if(cntTemp > maximumCounts ) maximumCounts = cntTemp;
cntTemp = 0;
}
}
}
/**
This is our final Answer.
**/
cout << maximumCounts << endl;
return 0;
}
关于c++ - 在给定矩阵中找到最大的盆地大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24336686/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在学习http://ruby.railstutorial.org/chapters/static-pages上的RubyonRails教程并遇到以下错误StaticPagesHomepageshouldhavethecontent'SampleApp'Failure/Error:page.shouldhave_content('SampleApp')Capybara::ElementNotFound:Unabletofindxpath"/html"#(eval):2:in`text'#./spec/requests/static_pages_spec.rb:7:in`(root)'
点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度; 在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。
我有以下内容:text.gsub(/(lower)(upper)/,'\1\2')我可以将\2替换为大写吗?类似于:sed-e's/\(abc\)/\U\1/'这在Ruby中可行吗? 最佳答案 查看gsub文档:str.gsub(模式){|匹配|block}→new_str在block形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量将被适当设置。block返回的值将替换为每次调用的匹配项。"alowerupperb".gsub(/(lower)(upper)/){|s|$1+""+$2.upcase}