1. 广告排名区间 (10分)
问题背景
shifen广告消费预估系统可以估计出一段时间内一个特定的广告在检索结果中排在各个位置的几率。比如系统对某广告的输出如下:
p1 = 0.03, p2 = 0.08, p3 = 0.04 ……
这说明该广告展现在第1位的概率是 3%,展现在第2位的概率是 8%,展现在第3位的概率是 4%……
问题是:如何给出一个排名估计区间[i, j],使得广告出现在该区间中的概率大于或等于一个预设值p,同时这个区间所包含的元素尽可能的少。也可用数学语言来描述:给定数p和数列 p1, p2, … , pn,求 i和 j (1 <= i <= j <= n),在满足pi + pi+1 + … + pj >= p的前提下让j-i 最小。
一般来说,pi只需保留6位小数就足够了。这样,若令ai=106pi,a=106p,则a和所有的ai均为[0,106]之间的整数。这样就避免了对实数的处理。
输入格式
第一行包含一个整数n (1 <= n <= 100,000)。
以下n行每行包含一个[0,106]内的整数,依次为a1,a2,…,an。这n个整数之和保证不超过106。
最后一行包含一个[0,106]内的整数a。保证所有ai之和不小于a。
输出格式
输出仅一行,包含一个整数,即j – i的最小值。
样例输入
7
5
8
4
7
10
5
2
18
样例输出
2
样例解释
a2=8, a3=4, a4=7之和为19,满足条件。而任何两个相邻数之和均小于18。
--------------------------------------------------------------------------------------------------------------
2. LZW网页判重 (20分)
问题背景
有一种简单的网页判重的方法,通过求两个网页内容的最长公共子序列(LCS)长度来判定两个网页的相似程度。如:
(网页A)老师:请用“果然”造句。
(网页B)学生:先吃水果,然后喝汽水……
它们的最长公共子序列为“果然”,长度为2。注意这里的“子序列”并不要求连续。
类似的,下面两个网页:
(网页A)老师:请用“果然”造句。
(网页B)学生:先吃水果,然后喝汽水,果然拉肚子……
最长公共子序列还是“果然”,长度为2。但不难看出,由于“果然”两个字在网页B中也曾连续出现,第二组网页比第一组更加“相似”。为了区分开这两种情况的区分度,我们改用一种称为LZW的理论。为了严格的叙述相似度的计算方法,我们首先定义“文本单元”。
假定网页用一个不包含空白字符(空格、回车换行、水平制表符)的字符串来表示。它只包含纯文本,没有标签。在计算相似度之前,你应该首先对该字符串 进行处理,划分成一个个“文本单元”。每个文本单位可以是一个中文字、英文单词(由一个或多个连续的半角英文字母和数字组成,正规表达式为[a-zA- Z0-9]+)、或者一个标点符号。
根据上述定义,同一个标点符号的全角和半角应该被作为不同的文本单元,尽管他们看起来可能很相近;每个单独全角英文和全角数字都应该被看成一个单独的文本单元,而连续的半角英文字母和数字应被看成一个整体。总之,全角的字符可以与中文字同等对待。
这样,网页被看成文本单元序列。例如,网页“内容?123456??web2.00#”切分出的文本单元序列为(为了显示方便,用下划线分隔各文本单元):
内_容_?_1_2_345_6_?_?_web2_._00_#
而网页“why内容相似??1234567890,web#00”的切分结果为:
why_内_容_相_似_?_?_1234567890_,_web_#_00
黑体部分给出了两个网页的一个公共子序列。注意“内容”、“??”分别在两个网页中都是连续出现的文本单元。为了奖励这种情况,LZW规定一段由连 续k个文本单元组成的字符串权值为k2。在刚才的例子中,“内容”、“??”的权值均为4。但“00”是一个数字串,应当被看成一个单独的文本单元。所以 权值仅为1。
根据上述规则,公共子序列“内容 ?? 00”的权值为22+22+1=9。在所有可能的子序列中,这个权值是最大的。
给定两个网页,求他们的LZW相似度,即所有可能的公共子序列中的最大权值。
注意
1) 输入的网页内容以GBK编码
2) 除了大小写英文字母和数字之外的其他半角字符均视为标点符号。
输入格式
包含两行,分别是网页A和B对应的字符串(不包含空白字符)。每行至少包含5个字节,最多包含200个字节
输出格式
输出仅一行,包含一个整数,为两个网页的LZW相似度。
样例输入
内容?123456??web2.00#
why内容相似??1234567890,web#00
样例输出
9
样例解释
尽管两个网页里看上去都有“123456”但一方面第一个网页中混杂的全角和半角字符,而另一方面,即使全部改成半角字符,由于数字串“123456”和“1234567890”将分别看成一个单独的文本单元,因此无法部分匹配。
提示:
如何处理汉字?
答:如非特别说明,astar比赛中的所有汉字输入输出均用GBK编码。GBK 采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。 这是一个显示中西文混合字符串的参考程序。通过上面的分析可以得出,如果是汉字,则首字节在81-FE 之间,其最高位为1,所以补码小于0,应连续显示两个字节;如果是西文字符,则首字节在00-7F之间,其最高位为0,补码大于等于0,只需显示一个字 节。
#include <stdio.h>
char *str="汉字里有english也能正确显示,hehe";
int main() {
int i = 0;
while (str[i] != '/0') {
if(str[i] < 0) {
printf("%c%c/n", str[i], str[i+1]);
i++;
}
else {
printf("%c/n", str[i]);
}
i++;
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------
3. 钉子与木板 (30分)
问题背景
墙上有n个钉子,编号为1, 2, ..., n。其中钉子i的横坐标为i,纵坐标初始为xi。可以进行两种操作:
0 k v:移动操作。竖直移动钉子k,坐标变为(k, v)。
1 s t v:测试操作。若在高度为v处放一块横坐标范围是[s,t]的水平木板,它将下落到什么高度?换句话说,求出钉子s, s+1, s+2, …, t的纵坐标中,不超过v的最大值。如果这些钉子的高度全部大于v,则木板将落到地上,高度为0。
注意,在测试操作时,水平木板只是用来测试的“临时木板”,将在测试后立即被拿走,不会影响到后续测试工作。
输入格式
第一行包含两个整数n, m,即钉子的个数和操作的个数(1<=n,m<=105)。以下n行每行一个不超过109的非负整数,即xi。以下 m 行为各操作 (1 <= k <= n, 1 <= s < t <= n, 1 <= v <= 109 )
输出格式
按照输入的顺序,对于每个测试操作输出一个整数,即该测试水平木板的最后高度。
样例输入
5 4
1
3
5
7
9
1 2 4 6
0 3 10
1 3 5 7
1 3 5 5
样例输出
5
7
0
---------------------------------------------------------------------------------------------------------------------------
4. 圆面覆盖 (40分)
问题背景
在平面上有一个长为L,宽为W的长方形,左下角坐标为(0,0),右上角坐标为(L,W)。给定一些圆,第i个圆的圆心坐标为(xi,yi),半径为Ri。
你的任务是求最小的正实数k,使得把每个圆的半径变为原来的k倍后(即:第i个圆半径变为kRi,圆心位置不变),长方形将被这些圆完全覆盖。换句话说,长方形内部或边界上的任意点均至少在一个圆的内部或边界上。
输入格式
输入第一行包含三个整数n, L, W(1<=n<=50,1<=L,W<=1000),即圆的个数、长方形的长和宽。
以下n行,每行三个不超过1000的正整数xi, yi和Ri
输出格式
仅一行,包含一个实数k,保留小数点后三位。
样例输入
1 2 2
1 1 1
样例输出
1.414