SGi's Blog

A long run.

数学教育的进化(The Evolution of Math Teaching)

类归于: Mathematics — SGi at 7:45 下午 on 星期天, 十月 26, 2008

* 十七世纪 :
农民(peasant)的一袋土豆卖了10美元。他的成本为4/5的销售价格。他的利润是多少?
* 十八世纪前期:
农民(farmer)的一袋土豆卖了10美元。他的成本为4/5的销售价格,也就是8美元。他的利润是多少?
* 十八世纪后期(新数学) :
一位农民用土豆组成的集合P换了钱组成的集合M。集合M的势等于10 ,M中每个元素的值为1美元 。画10个大圆点代表集合M中的元素。成本集合C也这样表示,它比M少两个大圆点。把C作为M的子集并回答如下问题:利润集合的势是多少?
* 20世纪80年代:
农民的一袋土豆卖了10美元。他的生产成本是8美元,他的利润是2美元。把“土豆”加上下划线 ,并与你的同学讨论。

* 20世纪90年代:
农民的一袋土豆卖了10美元。他或她的生产成本是0.8倍的他或她的收入。用你的计算器画出收入-成本图像。运行”马铃薯”程序,以确定利润。与你小组的同学讨论你的结果。写一篇简短的论文,在现实世界中的经济学中分析这个例子。

* 1960s:
A peasant sells a bag of potatoes for $10. His costs amount to 4/5 of his selling price. What is his profit?
* 1970s:
A farmer sells a bag of potatoes for $10. His costs amount to 4/5 of his selling price, that is, $8. What is his profit?
* 1970s (new math):
A farmer exchanges a set P of potatoes with set M of money. The cardinality of the set M is equal to 10, and each element of M is worth $1. Draw ten big dots representing the elements of M. The set C of production costs is composed of two big dots less than the set M. Represent C as a subset of M and give the answer to the question: What is the cardinality of the set of profits?
* 1980s:
A farmer sells a bag of potatoes for $10. His production costs are $8, and his profit is $2. Underline the word “potatoes” and discuss with your classmates.
* 1990s:
A farmer sells a bag of potatoes for $10. His or her production costs are 0.80 of his or her revenue. On your calculator, graph revenue vs. costs. Run the POTATO program to determine the profit. Discuss the result with students in your group. Write a brief essay that analyzes this example in the real world of economics.

来源:http://www.tvdsb.on.ca/banting/courses/math/Comics.htm

恭喜靖靖全国物理竞赛夺金!

类归于: Campus Life — SGi at 6:35 下午 on 星期六, 十月 25, 2008

恭喜恭喜,靖哥哥您太牛了,ORZ


2008年信息学奥林匹克联赛上海赛区复赛通知

类归于: Informatics — SGi at 6:06 下午 on 星期四, 十月 23, 2008

1、复赛选手名单:

提高组:

准考证 姓名 性别 在读学校
3372 邵欣蔚 延安中学
3373 杨亦骁 延安中学
3004 姜家骐 向明中学
3007 罗佳浩 交大附中
3008 江爻坤 交大附中
3009 周之帆 交大附中
3010 张笑诚 交大附中
3011 王骏元 交大附中
3012 尹一帆 交大附中
3013 交大附中
3015 康天余 交大附中
3016 金卓文 交大附中
3017 交大附中
3018 方礼冬 交大附中
3024 唐鸿飞 大同中学
3374 彭中昱 大同中学
3031 夏骐萌 格致中学
3032 席文骏 格致中学
3033 邓凝旖 格致中学
3034 孟亦田 格致中学
3035 庄汉嘉 格致中学
3036 樊灵君 格致中学
3037 田琨 格致中学
3039 袁辛未 格致中学
3040 虞陆洋 格致中学
3041 孙思逸 格致中学
3043 张文纲 格致中学
3045 张凯帆 格致中学
3049 胡逸然 格致中学
3054 顾天瑜 格致中学
3056 梁楹成 上外高中
3058 师大二附中
3068 倪彬拓 华东师大一附中
3072 陈嘉文 西南位育中学
3073 吴益明 西南位育中学
3076 黄金阳 西南位育中学
3078 沈昱 西南位育中学
3079 宋安梁 西南位育中学
3081 顾佳毅 西南位育中学
3082 陆懿庭 西南位育中学
3084 陆智尧 西南位育中学
3085 袁野 西南位育中学
3086 陈闻达 西南位育中学
3090 王一杰 西南位育中学
3091 毛冬元 西南位育中学
3095 张博文 新中中学
3102 许欣昊 建平中学
3103 罗顺彦 建平中学
3105 柳萌宇 建平中学
3106 刘诗聪 建平中学
3107 张君霄 建平中学
3108 张泽众 建平中学
3109 李文颖 建平中学
3110 李志强 建平中学
3112 朱皇 建平中学
3114 张晓 建平中学
3116 魏云晟 建平中学
3117 彭毅 建平中学
3118 曾鲁闽 建平中学
3121 季晓枫 上海市实验学校
3123 罗若天 上海市实验学校
3124 龚光仪 上海市实验学校
3125 王子豪 上海市实验学校
3126 刘丰 上海市实验学校
3127 张惠楚 上海市实验学校
3128 陈晨 上海市实验学校
3129 高明远 上海市实验学校
3130 张闻宇 上海市实验学校
3133 杨筱茜 上海市实验学校
3134 储之恒 上海市实验学校
3135 陆东杰 华东师大二附中
3136 沙亦鹏 上海市东昌中学
3138 杨喆悦 上外附中
3139 樊能 上外附中
3140 储骏 控江中学
3144 肖阳 育才中学
3145 刘萌杰 育才中学
3146 杨坚 育才中学
3150 裘文翔 晋元高级中学
3154 蒋书奇 宜川中学
3158 徐凌枫 宜川中学
3159 宜川中学
3160 沈雯婷 宜川中学
3161 徐至行 宜川中学
3162 陈文琦 宜川中学
3163 王浩宇 宜川中学
3166 张瑞杰 卢湾高级中学
3168 虞若奇 晋元高级中学
3169 竺云嘉 上外附中
3172 朱力旻 上外附中
3179 施嘉恒 敬业中学
3181 石炜昕 徐汇中学
3182 华师大一附中
3183 北虹高级中学
3184 鲍炜俊 北虹高级中学
3186 张宇翔 控江中学
3188 陆修远 上外附中
3189 於心力 交大附中
3191 陶育东 延安中学
3192 虞世泽 位育中学
3193 陈良皓 上外附中
3195 蔡隆祺 风华高级中学
3196 刘忆舟 西南位育
3197 张友嘉 徐汇中学
3200 姚睿捷 上海市第二中学
3203 王力功 华育中学
3204 刘径舟 华育中学
3205 张亦凡 华育中学
3207 冯丹 二附中
3209 王逸敏 二附中
3210 张贻辰 二附中
3211 赵成浩 二附中
3214 蔡磊卿 二附中
3217 邓永行 二附中
3220 陆天 二附中
3221 许可禹露 二附中
3222 林之雨 二附中
3223 姜泽勋 二附中
3224 贺天行 二附中
3225 陈宇翔 二附中
3226 蒋林浩 二附中
3227 吴佳俊 二附中
3229 陈未蒙 二附中
3230 郑诗桦 二附中
3231 毕颖杰 二附中
3232 王必成 二附中
3233 蒋晓航 二附中
3234 洪彦 二附中
3235 张颿 二附中
3236 金昊衠 二附中
3237 朱晓伟 二附中
3241 吴逸飞 二附中
3242 严枭 二附中
3243 胡瀚林 二附中
3249 周小博 二附中
3251 季宇 二附中
3254 孙炜程 二附中
3255 符核 二附中
3256 陶怡乐 二附中
3257 蒋羽辰 二附中
3260 艾可 二附中
3266 高丰韡 二附中
3377 宋方睿 二附中
3268 张宸元 复旦附中
3269 周震宇 复旦附中
3270 周奕超 复旦附中
3271 张墨之 复旦附中
3273 甘全 复旦附中
3275 徐昊文 复旦附中
3276 李曙华 复旦附中
3278 伊俊袆 复旦附中
3279 俞维克 复旦附中
3281 王志骁 复旦附中
3282 黄俊骁 复旦附中
3283 张骏袆 复旦附中
3284 宣炎 复旦附中
3285 丁海乐 复旦附中
3291 陈树潜 复旦附中
3292 游钱皓喆 复旦附中
3297 陈皓 复旦附中
3380 李诚 复旦附中
3381 许昊文 上海中学
3357 施天麟 上海中学
3301 严冠文 上海中学
3302 周天奕 上海中学
3303 周若凡 上海中学
3304 贾蕴哲 上海中学
3306 孙旭东 上海中学
3314 胡优 上海中学
3315 瞿飞 上海中学
3317 顾杨 上海中学
3318 殷程烨 上海中学
3319 丁子旭 上海中学
3320 陈晓阳 上海中学
3321 贾俊连 上海中学
3361 洪玠巍 上海中学
3322 陶亦心 上海中学
3323 张雪逸 上海中学
3324 陈逸尘 上海中学
3325 赵立宏 上海中学
3327 吴翔宇 上海中学
3328 李文进 上海中学
3329 林恺强 上海中学
3331 杨帆 上海中学
3362 谢聪 上海中学
3332 潘雨辰 上海中学
3333 曹瑞晴 上海中学
3382 曹钦翔 上海中学
3383 张赜隐 上海中学
3384 王孟晖 延安中学
3363 朱晓骅 上外附中
3364 王家雷 上海中学
3334 胡翰彬 延安中学
3366 陈程 华师大二附中
3385 陈涵洋 上海市南洋模范中学
3335 陆晟 上海中学
3386 沈诗旸 南洋中学
3367 彭健祥 大同中学
3368 吕天予 市西中学
3371 袁弈 上海市复兴高级中学
3387 葛煜庭 上外附中
3388 葛卓琛 位育高中
3390 朱晓 中国中学
3392 施建行 控江中学

2、复赛时间:
高中组(提高组):11月15日(周六)上午8:30至11:30竞赛。下午统一测试与确认成绩,选手不得缺席。组委会提供午餐。
初中组(普及组):11月15日(周六)下午1:30至4:30竞赛。

3、复赛地点:
提高组(高中组)、普及组(初中组):
华东师大二附中  地址:晨晖路555号

4、复赛确认注册:
时间:2008年11月8日(周六)、11月9日(周日)两天内上午9:00至下午4:00。
认证时请持参加复赛选手的有效证件(身份证、户口本、学生证,其中的任何一证均可视为证件)。认证同时交纳复赛的费用,进行选手登记,登记内容包括:姓名、性别、所在学校、年级、联系电话等。同时发竞赛准考证及确认考场。
超过注册时间或没有登记注册的选手均认为自动放弃复赛。
复赛报名注册地点:上海市科技艺术教育中心
地址:岳阳路1号 教育会堂二楼
联系电话:64338132
联系人:裘黎明、余晓清

5、复赛环境:
操作系统为WINDOWS XP。
编程语言:Free Pascal 2.2.0 For Windows 、DEV C++ 4.9.9.2。
在竞赛中注意程序编写与存盘的严格规定:程序中出现的文件名与程序存盘文件名必须使用小写字母。程序文件指源文件。

第十四届全国信息学奥林匹克联赛
“二附中杯”上海赛区组委会
2008年10月23日

[原创]USACO 2008年10月分组赛中文译题

类归于: Informatics — SGi at 11:09 下午 on 星期三, 十月 22, 2008

Problem 1: Bovine Bones [Rob Kolstad, 2008]

Bessie十分喜欢角色扮演游戏,所以他说服了Farmer John带她到Hobby Shop去,现在Bessie有三颗骰子,这些骰子分别有S1,S2,S3面。(2 <= S1 <= 20; 2 <= S2 <= 20; 2 <= S3 <= 40)
Bessie不停的扔啊扔,试图找出这三枚骰子最常出现的和是多少。
现在给出这三枚骰子各有几面,请你计算出这三个骰子最常出现的和是多少,如果不止一个和出现同样的次数,输出最小的那个和。
输入格式:
仅一行,S1,S2,S3用空格分隔
输出格式
仅一行,出现几率最高的和中最小的一个。
样例输入:
3 2 3
样例输出:
5
样例说明:
一下是所有可能出现的情况:
1 1 1 -> 3  1 2 1 -> 4  2 1 1 -> 4  2 2 1 -> 5  3 1 1 -> 5  3 2 1 -> 6
1 1 2 -> 4  1 2 2 -> 5  2 1 2 -> 5  2 2 2 -> 6  3 1 2 -> 6  3 2 2 -> 7
1 1 3 -> 5  1 2 3 -> 6  2 1 3 -> 6  2 2 3 -> 7  3 1 3 -> 7  3 2 3 -> 8
5和6都出现了5次,所以最终的答案是5。

Problem 2: Building A Fence [Jeffrey Wang, 2007]

勤奋的Farmer John想要建造一个由四面围成的栅栏来关住那些奶牛。他现在有一块长度为N(4 <= N <=2,500)的长木板,他需要把这块长木板切成边长均为正整数的四块,使得他能建造一个栅栏。
请问他有多少种不同的切割方式能使切割出来的木板围成一个四面的栅栏。
注意:
1.    不要考虑对称性的问题,不需要去除对称的方案和类似的复杂问题。
2.    栅栏围成的面积必须大于0
3.    结果可以用32位整数存储
输入格式:
仅一行,整数N
输出格式:
仅一行,Farmer John能将木板分割开来并能围成四边形的方案数。
样例输入:
6
样例输出:
6
样例解释:
Farmer John有10中方法将木板分成四块:(1, 1, 1,3); (1, 1, 2, 2); (1, 1, 3, 1); (1, 2, 1, 2); (1, 2, 2, 1); (1, 3,1, 1); (2, 1, 1, 2); (2, 1, 2, 1); (2, 2, 1, 1);(3, 1, 1, 1).
其中有四种情况是不能围成一个四边形的:(1, 1, 1, 3), (1, 1, 3, 1), (1, 3, 1, 1), (3,1, 1, 1)

Problem 3: Watering Hole [Paul Christiano, 2007]

Farmer John决定给他分别用1到N(1 <= N <= 300)分别编号的牧草浇水,他可以直接在一颗牧草旁边直接挖一口井来获得水,也可以用管子从任意有水的牧草那里来获得水。
在第i颗牧草旁边挖一口井的代价为Wi(1 <= W_i <= 100,000),用管子连接第i与第j颗牧草的代价为Pij(1 <= Pij <=100,000; Pij = Pji; Pii=0)
请求出Farmer John浇灌这些牧草花费的最小代价。
输入格式:
第一行,一个整数N
第二行到第N+1行,行i+1表示Wi
第N+2行到第2N+1行,行N+1+i包含N个用空格分隔开来的整数,每行第j个数字即是Pij
输出格式:
仅一行,Farmer John浇灌这些牧草的最小代价。
样例输入:
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
样例输出:
9
样例解释:
总共有4颗牧草,在每个牧草旁边挖一口井的代价分别为1,4,4,3,每个点连接一根管子的价格用邻接矩阵给出。最优解为在第4颗牧草旁边挖一口井并把所有的牧草用连接起来,总代价为:3 + 2 + 2 + 2 = 9。

Problem 4: Pasture Walking [Neal Wu, 2007]

有N (2 <= N <= 1,000)头奶牛,分别编号为1到N。还有N颗牧草分别编号为1到N。简单起见,第i头奶牛都盯着第i颗牧草。
有几对牧草分别用一些小路连接了起来,总共有N-1条双向的小路,小路i连接了Ai及Bi颗牧草(1 <= Ai <= N; 1 <= Bi <= N),小路的长度为Li (1 <= Li <= 10,000)
保证任意两颗牧草总能通过小路走到,也就是说这些小路构成了一棵树。
奶牛是群居性的动物,很喜欢串门。奶牛们会问你Q次问题(1 <= Q <= 1,000),每次询问的内容很简单,就是从p1颗牧草到p2颗牧草最短的距离是多少。(1 <= p1 <= N; 1 <=p2 <= N)
输入格式:
第一行,两个用空格分隔的整数:N和Q
第二行到第N行,第i+1行包含三个用空格分隔的整数Ai,Bi,Li
第N+1行到第N+Q行,每行包含两个用空格分隔的整数p1,p2
输出格式:
共Q行,每行包含每次询问的最短距离的值。
输入样例:
4 2
2 1 2
4 3 2
1 4 3
1 2
3 2
输出样例:
2
7
样例解释:
询问1:1->2 总代价为2
询问2:3->4->1->2 总代价为7

Problem 5: Wheel Rotation [Fatih Gelgi, 2008]

Farmer John有一台老式的打谷机,需要在不同的齿轮上安装皮带来带动它工作。这个打谷机的引擎是1号滑轮顺时针转动,通过一根皮带带动2号滑轮转动,2号滑轮也通过皮带带动3号滑轮转动,依次类推,总共有N个滑轮,N-1根皮带(2 <= N <= 1,000)。

上面的这个图示给出了皮带的两种不同的连接方式,第一种成为直接连接,会被动滑轮与主动滑轮同向旋转,第二种成为交错连接,会使得被动滑轮反向旋转。
给出所有皮带的连接方式,已知1号滑轮是顺时针旋转的,请问第N号滑轮是怎么旋转的。
每条皮带用三个整数描述:
Si:皮带的主动轮编号
Di:皮带的被动轮编号
Ci:连接方式(0代表直接连接,1代表交错连接)
很不幸,Farmer John并不是按照序号依次给出这些数据的。

下面是一个N=4的例子,2与3之间使用直接连接,所以2和3都是顺时针旋转,3和4之间使用交错连接,所以4号滑轮是逆时针旋转的。

输入格式:
第一行,一个整数N
第二行到第N行,每行分别用三个整数Si,Di,Ci描述一条皮带。
输出格式:
仅一行,一个整数表示第N个滑轮的旋转方向,0代表顺时针,1代表逆时针。
样例输入:
4
2 3 0
3 4 1
1 2 0
样例输出:
1

Problem 6: Power Failure [Rob Kolstad, 2008]

一次严重的暴风雨破坏了一些农场电力网络的一些线路!Farmer John有一张包含(2 <= N <=
1,000)所有N个电线杆的地图,分别用1到N标号,每个电线杆都用一个有序数对(xi,yi)来表示(-100,000 <= x_i <=100000; -100,000 <= y_i <= 100,000)
有W (1 <= W <= 10,000)条电力线连接电线杆Pi与Pj (1 <= Pi <= N; 1 <= Pj <= N)
他需要从1号电线杆往N号电线杆输送电力(因为电力线路的损坏,可能需要通过一些中转的电线杆)
给出这N个电线杆和暴风雨后依然可用的电力线,请求出如果要恢复从1号电线杆到N号电线杆,所需要的连接的电力线长度的最小值,所有的电力线长度都可以用实数M (0.0 < M
<= 200,000.0)来表示。
下面左图是一个有9个电线杆和3条电力线的电力网,对于这个任务M=2.0,最好的恢复方案是连接4号与6号电线杆以及6号与9号电线杆。
After the storm              Optimally reconnected

1
2
3
4
5
6
7
8
9
3  . . . 7 9 . . . . .          3  . . . 7 9 . . . . .
                                          /
2  . . 5 6 . . . . . .          2  . . 5 6 . . . . . .
                                        /
1  2-3-4 . 8 . . . . .          1  2-3-4 . 8 . . . . .
   |                               |
0  1 . . . . . . . . .          0  1 . . . . . . . . .
 
   0 1 2 3 4 5 6 7 8 9             0 1 2 3 4 5 6 7 8 9

总长度: 1.414213562 + 1.414213562 = 2.828427124 .
输入格式:
第一行,用空格分隔的两个整数N,W
第二行,一个实数M
第三行到第N+2行,每行包含两个用空格分隔的整数xi,yi
第N+3行到第N+2+W行,每行包含两个用空格分隔的整数Pi,Pj
输出格式:
仅一行,一个整数,为最小电力线长度1000倍的整数部分,如果恢复方案不存在,输出-1。
样例输入:
9 3
2.0
0 0
0 1
1 1
2 1
2 2
3 2
3 3
4 1
4 3
1 2
2 3
3 4
样例输出:
2828

清帝之惑之雍正解题报告

类归于: Informatics — SGi at 11:35 下午 on 星期二, 十月 21, 2008

题目描述

source:vijos1012

。。。(省略一堆废话)
雍正将大致的情况告诉了你,并且说:大清一共有n个大城市,所有的大城市都不在同一个地点,同时我们对这n个城市从1到n进行编号;对于一个城市k,他有两个属性,一个是Xk,一个是Yk,分别表示这个城市所处的经度和纬度。请你告诉他问题的结果:L,即运河长度。(你可以假定地球是平面的)

输入

第1行,一个整数n。
从第2行到n+1行,按照i从小到大顺序,每行两个整数Xi,Yi,代表编号为i的城市的经度和纬度。
其中2<=n <=100000,1<=Xi,Yi<2^31。

输出

一个实数L(保留三位小数)

分析

题目简单的说就是给出平面上N个点,求最近点对,这题N有100000,直接做的后果就是这样:

编译通过…
测试数据 01:运行超时…
测试数据 02:运行超时…
测试数据 03:运行超时…
测试数据 04:运行超时…
测试数据 05:运行超时…
测试数据 06:运行超时…
测试数据 07:运行超时…
测试数据 08:运行超时…
测试数据 09:运行超时…
测试数据 10:运行超时…
————————-
Unaccepted 有效得分:0 有效耗时:0ms

可以容易想到两个优化:

1.按每个点的横坐标排序,枚举每个点的时候只要距离超过最小值就可以直接break

2.枚举的过程中,如果点i的横坐标和点j的横坐标的距离大于最小值也可以直接break

这样做的话,结果就会是这样:

编译通过…
测试数据 01:答案正确… 9ms
测试数据 02:答案正确… 40ms
测试数据 03:答案正确… 9ms
测试数据 04:答案正确… 0ms
测试数据 05:答案正确… 87ms
测试数据 06:答案正确… 9ms
测试数据 07:答案正确… 25ms
测试数据 08:答案正确… 150ms
测试数据 09:答案正确… 0ms
测试数据 10:答案正确… 118ms
————————-
Accepted 有效得分:100 有效耗时:447ms

这样这道题也算是解决了,其实这个问题还有更好的时间界,有两种都能达到O(nlogn)的时间

1.分治算法

用分治算法求S中最接近点对的基本思想是:选取一垂直线L∶x = m作为分割直线,将S的点分割为点数大致相同的2个子集S1和S2,使得:
S1={p∈S | p(x)≤m},S2={p∈S | p(x)>m}
其中:m是S中各点x坐标的中位数,因此S1和S2中点数大致相同,且S=S1∪S2。递归地在S1和S2上解最接近点对的问题,分别得到 S1和S2中的最小距离d1和d2,并设d=min{d1,d2}。用P1和P2分别表示在直线L左边和右边与其距离在d范围的点构成的两个垂直长条平面区域。
P1:{p∈P1 | (|m-x(p)|≤d)},P2:{p∈ P2 | (|x(p)-m|≤d)}
S中的最接近点对的距离或者是d,或者是某个{p,q}点对的距离,其中p∈P1,q∈P2。如果{p,q}是S中的最接近点对,则必有distance(p,q)
将上述描述简化如下:
(1)递归用L将节点集分成两个相等的部分;
(2)设d是d1和d2的最小值;
(3)删除离L超过d的节点;
(4)按照y维扫描剩下的节点,计算5个邻居的距离;
(5)如果距离小于d,更新d
下面我们分析分治算法的时间复杂度,由于步骤2-5是每个递归过程中都要去做的,我们先分析2-5。步骤2时间复杂度为O(1);步骤3时间复杂度为O(n);步骤4时间复杂度为O(1);步骤5时间复杂度为O(1),所以步骤2-5的时间复杂度为O(n)。步骤1递归地将平面S中的点分成两个相等的部分时间复杂度为O(logn),所以总的时间复杂度为O(n)* O(logn)=O(nlogn)。

平面扫描算法

平面扫描算法用一根垂直的线从左扫到右。在扫描的过程中,需要维护遇到的最近的节点对以及它们之间的距离d;还需要维护一个区域D,D是一个矩形,右边界由下一个扫描到的点p确定,宽为已经扫描的点中的最近点对的距离。每次遇到下一个点p,我们就执行以下操作:
(1)将在x轴上离p的距离超过d的节点从D中删除掉;
(2)确定p左边离p最近的点q;
(3)如果q点和p之间的距离小于d,更新最近的节点对和d;
下面我们分析平面算法的时间复杂度。首先对所有点按x坐标排序,时间复杂度为O(nlogn);其次在D中插入删除点,每次插入的时间复杂度为O(logn),因为共有n个点,所以时间复杂度为O(nlogn);然后比较p点的常数个邻居,时间复杂度为O(n)。所以平面扫描算法的时间复杂度为O(nlogn)。

PS:在Weiss的《数据结构与算法分析》有专门的一节来写了分治算法。

下面是AC Vijos1012的Pascal的程序:

?View Code PASCAL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
type
  dot = record x,y : extended; end;
 
var
  a : array[1..100000] of dot;
  n,i,j : longint;
  min,value : extended;
 
procedure qsort(l,r: longint);
var
  i,j: longint;
  y : dot;
  x : extended;
begin
  i:=l;
  j:=r;
  x:=a[(l+r) div 2].x;
  repeat
    while a[i].x &lt; x do inc(i);
    while x &lt; a[j].x do dec(j);
    if not(i&gt;j) then begin
      y:=a[i];
      a[i]:=a[j];
      a[j]:=y;
      inc(i); dec(j);
    end;
  until i&gt;j;
  if l&lt;j then qsort(l,j);
  if i&lt;r then qsort(i,r);
end;
 
function dist(a,b : dot):extended;
begin
  exit(sqrt(sqr(a.x-b.x) + sqr(a.y-b.y)));
end;
 
begin
  readln(n);
  for i := 1 to n do
    readln(a[i].x,a[i].y);
  qsort(1,n);
  min := maxlongint;
  for i := 1 to n do
    for j := i+1 to n do begin
      if a[j].x - a[i].x &gt;= min then break;
      value := dist(a[i],a[j]);
      if value &lt; min then begin
        min := value;
        break;
      end;
    end;
  writeln(min:0:3);
end.

滑雪解题报告

类归于: Informatics — SGi at 10:30 下午 on 星期二, 十月 21, 2008

题目描述

source:vijos1011,pku1088,SHTSC2002

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更长。事实上,这是最长的一条。

输入

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

输出

输出最长区域的长度。

分析

这题直接用DFS裸搜肯定TLE,明显可以用DP来解决。
用opt[i,j]记录从点node[i,j]出发的最短路径
状态转移方程很容易写出来
opt[i,j]=max{opt[i+1,j],opt[i-1,j],opt[i,j+1],opt[i,j-1] } +1
但是这道题的状态并不容易表示,所以计算opt的时候需要类似DFS的方法,这就是DP的本质——记忆化搜索。

下面是过Vijos 1011的Pascal代码:

?View Code PASCAL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const
  dx : array [1..4] of longint = (-1,0,1,0);
  dy : array [1..4] of longint = (0,1,0,-1);
 
var
  r,c,max,i,j,value : longint;
  node,opt : array[0..1000,0..1000] of longint;
 
function check(i,j : longint):boolean;
begin
  exit((i &gt;= 1) and (i &lt;= r) and (j &gt;= 1) and (j&lt;=c));
end;
 
function dp(i,j : longint):longint;
var
  k : longint;
begin
  if opt[i,j] &gt; 0 then exit(opt[i,j]);
  for k := 1 to 4 do
    if check(i+dx[k],j+dy[k]) then
      if (node[i+dx[k],j+dy[k]] &lt; node[i,j]) then
        if opt[i,j] &lt; dp(i+dx[k],j+dy[k]) + 1 then
          opt[i,j] := dp(i+dx[k],j+dy[k]) + 1;
  exit(opt[i,j]);
end;
 
begin
  max := -maxlongint;
  fillchar(opt,sizeof(opt),0);
  readln(r,c);
  for i := 1 to r do begin
    for j := 1 to c do
      read(node[i,j]);
    readln;
  end;
 
  for i := 1 to r do
    for j := 1 to c do begin
      value := dp(i,j);
      if value &gt; max then max := value;
    end;
  writeln(max+1);
end.
下一页 »