面试题:P1-数海岸线算法

这是一个比较偏僻的网站上的题目,做这个题目的原因是某同学去面试的时候遇到了这样的题目,然后问我如何做,遇上这样的问题不解决就不是我的风格了。

先给出这个网站的题目网址:http://jobs.p1.com/tech/costal.html

估计很少人上个这个网站,做个这个网站的题目更加少了,所以有公司拿这样的现成的题目考面试者,有面试者做过了的概率是很少的。不过只要学校不太糟糕,那么能做出这样题目的人,进个什么BAT不是什么难事吧。

同时贴出题目吧:

Coast Length


Puzzle ID: coast

The island municipality of Soteholm is required to write a plan of action for their work with emission of greenhouse gases. They realize that a natural first step is to decide whether they are for or against global warming. For this purpose they have read the
IPCC report on climate change and found out that the largest effect on their municipality could be the rising sea level.

The residents of Soteholm value their coast highly and therefore want to maximize its total length. For them to be able to make an informed decision on their position in the issue of global warming, you have to help them find out whether their coastal line
will shrink or expand if the sea level rises. From height maps they have figured out what parts of their islands will be covered by water, under the different scenarios described in the IPCC report, but they need your help to calculate the length of the coastal
lines.

Task

You will be given a map of Soteholm as an N×M grid. Each square in the grid has a side length of 1 km and is either water or land. Your goal is to compute the total length of sea coast of all islands. Sea coast is all borders between land and sea, and sea is
any water connected to an edge of the map only through water. Two squares are connected if they share an edge. You may assume that the map is surrounded by sea. Lakes and islands in lakes are not contributing to the sea coast.

Figure 1:

Gray squares are land and white squares are water. The thick black line is the sea coast. This example corresponds to Sample Input 1.

Input

The first line of the input contains two space separated integers N and M where 1 ≤ N, M ≤ 1000. The following N lines each contain a string of length M consisting of only zeros and ones. Zero means water and one means land.

Output

Output one line with one integer, the total length of the coast in km.


Sample Input 1

 
Sample Output 1

5 6

011110

010110

111000

000010

000000

 

20

To submit a solution to this problem, send an e-mail to [email protected]

Include your source code files as attachments and set the subjectline to coast.

You should receive an answer within minutes. (make sure the subjectline is exactly: coast)

出处:http://jobs.p1.com/tech/costal.html

看上面的图就大概能明白,就是上图四周是大海包围的,数海岸线的长度,其中中间空的算是湖岸线了,不能算是海岸线,这就是其中的难点。

主要算法要点:

1 以地图的四周,即地图的边沿,如下图黄色部分:

作为收拾搜索点,使用递归搜索,如果是0,代表是海水能渗入的地方,那么就做好标识,我的代码使用const char WATER = ‘2‘,标识;沿这样的点能走到的点都标识为WATER,这样就能标识出海水渗透到的格子,并和内湖的格子区分开来了。

2 第1步解决了标识和区分内湖的问题,然后就解决数海岸线的问题了,我们分开两步来数,第一步数最外边的海岸线,第二部数格子之间的海岸线;

即第一步数:

这里应该数作5条海岸线。

第二步数格子之间的海岸线:

这里应该数作30条海岸线,但是由于格子之间的海岸线会数重复,那么实际的海岸线应该是30/2=15条

最终5 + 15 = 20条海岸线。

理解了两个关键算法点之后,再写算法就不难了,只要处理好代码细节问题就好了。

由于这个网站的判断系统对我来说也比较新,故此对一个新系统的输入输出处理和判别系统都需要熟悉以下,故此多调试以下是必然的了。

最后给出AC的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;

const int MAX_N = 1001;
char arr[MAX_N][MAX_N];
int n, m;
const char WATER = '2';

inline bool isLegal(int r, int c)
{
	return 0<=r && 0<=c && r<n && c<m;
}

void fillWater(int r, int c)
{
	if (!isLegal(r, c)) return ;
	if (arr[r][c] != '0') return ;

	arr[r][c] = WATER;
	fillWater(r-1, c);
	fillWater(r+1, c);
	fillWater(r, c-1);
	fillWater(r, c+1);
}

int main()
{
	//freopen("in.txt", "r", stdin);
	scanf("%d %d", &n, &m);
	getchar();
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			char a = getchar();
			while (a != '0' && a != '1')
			{
				a = getchar();
			}///< handle io crazy problems.
			arr[i][j] = a;
		}
	}
	for (int i = 0; i < n; i++)
	{
		fillWater(i, 0);
		fillWater(i, m-1);
	}
	for (int j = 1; j+1 < m; j++)
	{
		fillWater(0, j);
		fillWater(n-1, j);
	}

	int outEdge = 0, inEdge2 = 0;

	for (int i = 0; i < n; i++)
	{
		if (arr[i][0] != WATER) outEdge++;
		if (arr[i][m-1] != WATER) outEdge++;
	}
	for (int j = 0; j < m; j++)
	{
		if (arr[0][j] != WATER) outEdge++;
		if (arr[n-1][j] != WATER) outEdge++;
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (arr[i][j] == WATER)
			{
				if (isLegal(i-1, j))
				{
					if (arr[i-1][j] != WATER) inEdge2++;
				}
				if (isLegal(i+1, j))
				{
					if (arr[i+1][j] != WATER) inEdge2++;
				}
				if (isLegal(i, j-1))
				{
					if (arr[i][j-1] != WATER) inEdge2++;
				}
				if (isLegal(i, j+1))
				{
					if (arr[i][j+1] != WATER) inEdge2++;
				}
			}
			else if (arr[i][j] != WATER)
			{
				if (isLegal(i-1, j))
				{
					if (arr[i-1][j] == WATER) inEdge2++;
				}
				if (isLegal(i+1, j))
				{
					if (arr[i+1][j] == WATER) inEdge2++;
				}
				if (isLegal(i, j-1))
				{
					if (arr[i][j-1] == WATER) inEdge2++;
				}
				if (isLegal(i, j+1))
				{
					if (arr[i][j+1] == WATER) inEdge2++;
				}
			}
		}
	}
	printf("%d", outEdge + (inEdge2>>1));
	return 0;
}
时间: 2024-10-23 02:34:00

面试题:P1-数海岸线算法的相关文章

【蓝桥杯】历届试题 幸运数

  历届试题 幸运数   时间限制:1.0s   内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的“筛法”生成. 首先从1开始写出自然数1,2,3,4,5,6,.... 1 就是第一个幸运数. 我们从2这个数开始.把所有序号能被2整除的项删除,变为: 1 _ 3 _ 5 _ 7 _ 9 .... 把它们缩紧,重新记序,为: 1 3 5 7 9 .... .这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去.注意,是序号位置,不是那个数本身能否

空间复杂度为O(1)的回文数判定算法

空间复杂度为O(1)的回文数判定算法 一.题设 实现空间复杂度为O(1)的回文数判定,输入为整型常数,要求输出判断是否为回文数. 要求格式如下: public boolean isPalindrome(int x) { //Your judge code } 二.概念 回文数(Palindrome)的定义:设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称n为一回文数:但若n=1234567,则n不是回文数. 特点: 1.负数.

三数和算法及其思考

三数和算法 1.三重循环 去获取每次值相加,获取到相对应的值 缺点:虽然简单实现,但是复杂度为n3,时间比较复杂 2.循环加双指针 先排序 然后外层循环 内层用双指针的模式去遍历和比较 相对而言 减少了一层循环,且比较过程中可以部分剪枝 变种:三数和最接近target的算法 思考:我们拿到一个题目的时候,遇到不熟悉的内容的时候经常会首先想到蛮干,然后写出来的内容就显得相对比较冗余和复杂.实际上我们应该首先把题干和结论用相对比较简洁的语言重新表述,比如符号,然后推理要实现的步骤,写一些简单伪代码,

查找第K小的数 BFPRT算法

BFPRT算法是解决从n个数中选择第k大或第k小的数这个经典问题的著名算法,但很多人并不了解其细节.本文将首先介绍求解这个第k小数字问题的几个思路,然后重点介绍在最坏情况下复杂度仍然为O(n)的BFPRT算法. 一 基本思路 关于选择第k小的数有许多方法 将n个数排序(比如快速排序或归并排序),选取排序后的第k个数,时间复杂度为O(nlogn). 维护一个k个元素的最大堆,存储当前遇到的最小的k个数,时间复杂度为O(nlogk).这种方法同样适用于海量数据的处理. 部分的快速排序(快速选择算法)

华为机试题——阿姆斯特朗数

描述: 如果一个正整数等于其各个数字的立方和,则该数称为阿姆斯特朗数 (亦称为自恋性数),1除外,如407 = 43+03+73就是一个阿姆斯特朗数. 试编程求n(n ≤ 65536)以内的所有阿姆斯特朗数. 接口说明 原型: int CalcArmstrongNumber(int n); 输入参数: int n: n ≤ 65536 返回值: n以内的阿姆斯特朗数的数量 知识点: 工程环境请使用VS2005 题目来源: 软件训练营 练习阶段: 初级 题目很简单,关键是了解阿姆斯特朗数,代码放在

P1问题求解相关算法

1. BP 利用matlab的线性规划工具箱,即linprog 主要思想:如何将P1问题转换为线性规划问题 即由3.1变为3.2 令x=[u; v],其中u,v均为正,a=u-v A=[phi,-phi]  (显示不了符号,读出来就好... ) b=s 则b=Ax=(u-v)=a=s 求解:x0=linprog(c,[],[],A,b,zeros(2*p,1)); 问题P1的最优解即为x0(1:p)-x0(p+1:2p) 注:这里要去掉绝对值,证明如下: 2. BPDN 基追踪去噪 利用quad

[经典面试题]完美洗牌算法

题目 有个长度为2n的数组{a1,a2,a3,-,an,b1,b2,b3,-,bn},希望排序后{a1,b1,a2,b2,-.,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法. 来源 2013年UC的校招笔试题 思路一 第①步.确定b1的位置,即让b1跟它前面的a2,a3,a4交换: a1,b1,a2,a3,a4,b2,b3,b4 第②步.接着确定b2的位置,即让b2跟它前面的a3,a4交换: a1,b1,a2,b2,a3,a4,b3,b4 第③步.b3跟它前面的a4交换位

九章算法面试题52 数数字

九章算法官网-原文网址 http://www.jiuzhang.com/problem/52/ 题目 数一数在0到n之间有多少个数字k(0<=k<=9).如n=12时,[0,1,2...,12]之间一共有5个1.分别包含在[1, 10, 11, 12]之中. 在线测试本题 http://lintcode.com/problem/digit-counts/ 解答 本题的解法要诀在于熟练的使用递归思路和预处理. 预处理: f[0] 代表了0-9中有多少个数字k.(肯定=1) f[1] 代表了00-

面试题中遇到的算法与js技巧(一)

近一周在忙着面试,本月第一次更博,甚是想念. 基本上大公司都会要求一些算法或者数据结构类的东西,挑了些有意思的敲了下.这方面自己还不是很精通,只能一步一个脚印来积累了. 1.根据查询字符串获取对象数据,可自行根据需求选择格式,此处以key:value的格式生成 // 这里可以使用正则匹配,但仔细向后,字符串的一些基本方法完全可以解决问题 var str = 'www.test.com/test?str1=aa&str2=bb&str3=cc'; function queryStr (str