解北大OJ1088滑雪问题的记录
问题:
|
Time Limit:1000MS |
Memory Limit:65536K |
|
|
Total Submissions:67600 |
Accepted:24862 |
Description
Michael 喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个 区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25
Source
示意图如下:
图一
思路一:从每个高度开始,不断搜索路径,直到局部极小处。然后找出最大值。但这种方式会导致搜索重复的路径。
思路二:可用动态规划,剔除思路一中需要重复搜索的路径,大大减少搜索次数。
{动态规划的经典的例子为找两城市之间的最短路径。
图二
从A到F的所有路径穿过图中串着E和D的竖线,假设E在最短路径上,那么从A到E的路径也应该选最短的,否则将有另外一条较短的从A到E的路径A’—>E’->F更短;往前推,从A到E的路径穿过B和C,假设B在最短路径上,那么从A到B的路径也应该选最短的,从A到E的一条可能最短路径为从A到B的最短路径+B和E之间的距离。C和D点同理。
因此,从A点出发,先得出A->B和A->C的最短路径,然后再得出A->E和A->D的最短路径,最后得出A->F的最短路径。
如图,在得到A->B和A->C的最短路径后,求A->E和A->D的最短路径时,减少了A->B和A->C的两次搜索。在得到A->E的最短路径时,剔除了A->B->E,在得到A->D的最短路径时,剔除了A->C->D,这样在得到A->F的最短路径时,又减少了两次搜索。而且减少的搜索次数是同节点个数N成正比的。通过记录逐段的搜索结果,达到减少搜索次数的目的。}
因此此题可以按照高度值,从高到低,逐次求得到达每个点的最长滑坡,最后再求出最长的滑坡。如图一,从A点到E点的最长滑坡为A->F->E.A点能影响到达F点和E点的最长滑坡,而F点也能影响到达E点的最长滑坡,因此当高度从A点变为F点时,到达E点的最长滑坡已经能知道应该从A->E改为A->F->E.假设从E点到B点还有其他路径的话,那么从A到E点的最长滑坡的确定就能减少搜索次数。时间复杂度为O(n)。
例如:
input
2 3
2 5 3
6 1 2
Output
求解过程为:
1.1、2、2、3、5、6各点初始化滑坡长度值为1;
2.6影响上面的2和右面的1,使他们的长度值分别加1变为2;
3.5影响右面的3,使其长度值加1变为2;
4.3影响下面的2,使其长度值加2变为3;
5.6上面的2处于局部极小(谷底)不影响;
6.3下面的2影响左面的1,使其长度值加3变为4;
7.1处于局部极小(谷底)不影响。
得到最大值为4.
附录:
这是我在北大OJ里提交的AC源代码,但是在Time和Memory方面还有待提高。其中在判断某点四个方向上的情况时,并未有效减少对于不可能的方向的情况的判断,而且代码看起来冗余。用一维数组表示的二维数组,动态分配的内存。说来也比较巧,当我做完后,在网上搜索了下,发现有些人的代码跟我的几乎差不多。
Source Code
|
Problem:1088 |
User:lilin_xuebao |
|
|
Memory:508K |
Time:32MS |
|
|
Language:G++ |
Result:Accepted |
· Source Code
#include<stdio.h>
#include<stdlib.h>
struct H
{
int height;
int length;
};
int cmp(const void *key,const void *data)
{
if((*(struct H**)key)->height < (*(struct H**)data)->height)
return 1;
return -1;
}
int main()
{
int rows=0,columns=0;
struct H * array=NULL;
struct H **temp=NULL;
int total;
scanf("%d%d",&rows,&columns);
total=rows*columns;
array=(struct H*)malloc(sizeof(struct H)*total);
temp=(struct H**)malloc(sizeof(struct H *)*total);
if(array == NULL||temp==NULL)return 0;
int i;
for(i=0;i<total;i++)
{
scanf("%d",&(array[i].height));
array[i].length=1;
temp[i]=&array[i];
}
qsort(temp,total,sizeof(struct H*),cmp);
int up,down,left,right;
int tempindex;
int max=-1;
for(i=0;i<total;i++)
{
tempindex=temp[i]-array;
up=tempindex-columns;
down=tempindex+columns;
left=tempindex-1;
right=tempindex+1;
if(up>=0&&array[tempindex].height>array[up].height)
{
if(array[tempindex].length+1>array[up].length)
{
array[up].length=array[tempindex].length+1;
}
}
if(down<total&&array[tempindex].height>array[down].height)
{
if(array[tempindex].length+1>array[down].length)
{
array[down].length=array[tempindex].length+1;
}
}
if((left+1)%columns!=0&&array[tempindex].height>array[left].height)
{
if(array[tempindex].length+1>array[left].length)
{
array[left].length=array[tempindex].length+1;
}
}
if(right%columns!=0&&array[tempindex].height>array[right].height)
{
if(array[tempindex].length+1>array[right].length)
{
array[right].length=array[tempindex].length+1;
}
}
if(array[tempindex].length>max)max=array[tempindex].length;
}
printf("%d",max);
free(array);
free(temp);
return 0;
}
解北大OJ1088滑雪问题的记录的更多相关文章
- syslog及syslog-ng详解 日志服务器
服务器的日志对系统工程师来说是至关重要的,一旦服务器出现故障或被入侵,我们需要查看日志来定位问题的关键所在,所以说对于线上跑的服务器而言日志应该合理的处理及管理.下面来 服务器的日志对系统工程师来 ...
- cocos2d-x项目过程记录(ios和android设备的适配)
(原创作品,欢迎转载,注明出处,谢谢:http://www.cnblogs.com/binxindoudou/admin/EditPosts.aspx?postid=3213645) 1.原理分析的博 ...
- MySQL日志文件之错误日志和慢查询日志详解
今天天气又开始变得很热了,虽然很热很浮躁,但是不能不学习,我在北京向各位问好.今天给大家分享一点关于数据库日志方面的东西,因为日志不仅讨厌而且还很重要,在开发中时常免不了与它的亲密接触,就在前几天公司 ...
- LeetCode高频148错题记录
3. Max Points on a Line 共线点个数3种解法 思路一:思考如何确定一条直线,两点法,确定斜率后带入一点.有三种情况,1. 两点重合,2. 斜率不存在,3. 正常算,依次以每个点为 ...
- 转:Parameter Server 详解
Parameter Server 详解 本博客仅为作者记录笔记之用,不免有很多细节不对之处. 还望各位看官能够见谅,欢迎批评指正. 更多相关博客请猛戳:http://blog.csdn.net/c ...
- [转]DNS服务器原理详解与Centos6.x下搭建DNS服务器
转自:http://blog.it985.com/8958.html DNS 数据库的记录:正解,反解, Zone 的意义 通过DNS解析过程详解这篇文章,我们知道了要想访问www.zmit.cn,最 ...
- [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径
相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...
- 背包【p1858】 多人背包(次优解 or 第k优解)
题目描述--->p1858 多人背包 分析: 很明显,这题是背包问题的一种变形. 求解 次优解or第k优解. 表示刚开始有点懵,看题解也看不太懂. 又中途去补看了一下背包九讲 然后感觉有些理解, ...
- 记一次uboot中gunzip解压速度慢的问题排查
背景 在项目中需要用到解压功能,之前还记录了下,将uboot解压代码移植到另外的bootloader中时,碰到的效率问题.最终查明是cache的配置导致的. https://www.cnblogs.c ...
随机推荐
- POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)
题目链接 题意: 公司被吞并,老员工几乎全部被炒鱿鱼.一共有n种不同的工具,编号1-N(代码中是0—N-1), 每种工具的加工时间为3—9天 ,但是现在老员工不在我们不知道每种工具的加工时间,庆幸的是 ...
- zoj 3778 Talented Chef(思维题)
题目 题意:一个人可以在一分钟同时进行m道菜的一个步骤,共有n道菜,每道菜各有xi个步骤,求做完的最短时间. 思路:一道很水的思维题, 根本不需要去 考虑模拟过程 以及先做那道菜(比赛的时候就是这么考 ...
- poj 1195 Mobile phones(二维树状数组)
树状数组支持两种操作: Add(x, d)操作: 让a[x]增加d. Query(L,R): 计算 a[L]+a[L+1]……a[R]. 当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一 ...
- 一台电脑同时运行多个tomcat配置方法
当第一个tomcat启动后,后面tomcat的server.xml中的端口不管怎么改,仍然会报端口冲突.后来在dos下运行才发现所有的tomcat都会去找CATALINA_HOME和CATALINA_ ...
- LA 3295 (计数 容斥原理) Counting Triangles
如果用容斥原理递推的办法,这道题确实和LA 3720 Highway很像. 看到大神们写的博客,什么乱搞啊,随便统计一下,这真的让小白很为难,于是我决定用比较严格的语言来写这篇题解. 整体思路很简单: ...
- bzoj2326: [HNOI2011]数学作业
矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...
- UVa 1152 4 Values whose Sum is 0
题意:给出n,四个集合a,b,c,d每个集合分别有n个数,分别从a,b,c,d中选取一个数相加,问使得a+b+c+d=0的选法有多少种 看的紫书,先试着用hash写了一下, 是用hash[]记录下来a ...
- uvalive 4255 Guess(拓扑排序)
算好题目,反正我没想到可以用图论做(虽然现在做的是图论专题= =) 首先是要把求每个位置上的值转化为求 “前缀和之差”,这是一个很有用的技巧 其次,由输入的(n+(n-1)+...+2+1)个符号,可 ...
- django - settings
1.doc - https://docs.djangoproject.com/en/1.6/topics/settings/ from django.conf import settings # 加载 ...
- 关于python中使用mongodb模块,save和insert的小问题
今天写python脚本的时候发现这样一个问题: import os , string , datetime ,pymongo; conn = pymongo.Connection("127. ...