Timus 1079. Maximum 要求输出指定数列中的最大值。
1079. Maximum
Time Limit: 2.0 second
Memory Limit: 16 MB
Consider the sequence of numbers ai, i = 0, 1, 2, …, which satisfies the following requirments:
- a0 = 0
- a1 = 1
- a2i = ai
- a2i+1 = ai + ai+1
for every
i = 1, 2, 3, … .
Write a program which for a given value of N (0 < N < 100000) finds the largest number among the numbers a0, a1, …, aN.
Input
Input contains not more than 10 lines containing one number N. The last line contains 0.
Output
For every N in the input write the coresponding maximum value found.
Sample
Problem Author: Emil Kelevedzhiev
Problem Source: Winter Mathematical Festival Varna '2001 Informatics Tournament
解法一:
1
using
System;
2
using
System.IO;
3
4
namespace
Skyiv.Ben.Timus
5
{
6
//
http://acm.timus.ru/problem.aspx?space=1
&num=1079
7
class
T1079a
8
{
9
static
void
Main()
10
{
11
new
T1079a().Run(Console.In, Console.Out);
12
}
13
14
void
Run(TextReader reader, TextWriter writer)
15
{
16
for
(; ; )
17
{
18
int
n
=
int
.Parse(reader.ReadLine());
19
if
(n
==
0
)
break
;
20
writer.WriteLine(((n
<
3
)
?
1
: GetMaximum(n,
3
,
1
,
1
)));
21
}
22
}
23
24
int
GetMaximum(
int
n,
int
x,
int
s1,
int
s2)
25
{
26
int
s0
=
s1
+
s2;
27
int
x1
=
x
*
2
-
1
;
28
if
(n
<
x1)
return
s0;
29
int
x2
=
x1
+
2
;
30
int
t1
=
(n
<
x1)
?
0
: GetMaximum(n, x1, s1, s0);
31
int
t2
=
(n
<
x2)
?
0
: GetMaximum(n, x2, s0, s2);
32
return
(t1
>
t2)
?
t1 : t2;
33
}
34
}
35
}
解法二:
1
using
System;
2
using
System.IO;
3
using
System.Drawing;
4
using
System.Collections.Generic;
5
6
namespace
Skyiv.Ben.Timus
7
{
8
//
http://acm.timus.ru/problem.aspx?space=1
&num=1079
9
class
T1079b
10
{
11
static
void
Main()
12
{
13
new
T1079b().Run(Console.In, Console.Out);
14
}
15
16
void
Run(TextReader reader, TextWriter writer)
17
{
18
Point[] list
=
GetList(
100000
);
19
for
(; ; )
20
{
21
int
n
=
int
.Parse(reader.ReadLine());
22
if
(n
==
0
)
break
;
23
writer.WriteLine(GetMaximum(list, n));
24
}
25
}
26
27
int
[] GetSequence(
int
n)
28
{
29
int
[] a
=
new
int
[n];
30
a[
1
]
=
1
;
31
for
(
int
i
=
2
; i
<
n; i
++
)
32
{
33
int
k
=
i
>>
1
;
34
if
((i
&
1
)
==
0
) a[i]
=
a[k];
35
else
a[i]
=
a[k]
+
a[k
+
1
];
36
}
37
return
a;
38
}
39
40
Point[] GetList(
int
n)
41
{
42
List
<
Point
>
list
=
new
List
<
Point
>
();
43
int
[] sequence
=
GetSequence(n);
44
int
max
=
int
.MinValue;
45
for
(
int
i
=
1
; i
<
sequence.Length; i
++
)
46
{
47
if
(sequence[i]
>
max)
48
{
49
max
=
sequence[i];
50
list.Add(
new
Point(i, max));
51
}
52
}
53
return
list.ToArray();
54
}
55
56
int
GetMaximum(Point[] list,
int
key)
57
{
58
int
low
=
0
, high
=
list.Length
-
1
;
59
int
mid
=
0
, key0
=
0
;
60
while
(low
<=
high)
61
{
62
mid
=
(low
+
high)
/
2
;
63
key0
=
list[mid].X;
64
if
(key
>
key0) low
=
mid
+
1
;
65
else
if
(key
<
key0) high
=
mid
-
1
;
66
else
return
list[mid].Y;
67
}
68
if
(key
<
key0) mid
--
;
69
return
list[mid].Y;
70
}
71
}
72
}
在解法二中,对 (0 < N < 105) 先求出所有的 a[n],然后求出此范围内的最大值项,共 103 项,如下:
( 1 1) ( 3 2) ( 5 3) ( 9 4) ( 11 5) ( 19 7) ( 21 8) ( 35 9)
( 37 11) ( 43 13) ( 69 14) ( 73 15) ( 75 18) ( 83 19) ( 85 21) ( 139 23)
( 147 26) ( 149 29) ( 165 30) ( 171 34) ( 277 37) ( 293 41) ( 299 47) ( 331 49)
( 339 50) ( 341 55) ( 555 60) ( 587 67) ( 595 69) ( 597 76) ( 661 79) ( 683 89)
( 1109 97) ( 1173 108) ( 1189 109) ( 1195 123) ( 1323 128) ( 1355 129) ( 1363 131) ( 1365 144)
( 2219 157) ( 2347 175) ( 2379 178) ( 2387 181) ( 2389 199) ( 2645 207) ( 2709 208) ( 2731 233)
( 4437 254) ( 4691 257) ( 4693 283) ( 4757 287) ( 4779 322) ( 5291 335) ( 5419 337) ( 5451 338)
( 5459 343) ( 5461 377) ( 8875 411) ( 9387 458) ( 9515 465) ( 9547 467) ( 9555 474) ( 9557 521)
(10581 542) (10837 545) (10923 610) (17749 665) (18771 674) (18773 741) (19029 752) (19093 753)
(19115 843) (21163 877) (21675 882) (21803 883) (21835 885) (21843 898) (21845 987) (35499 1076)
(37547 1199) (38059 1217) (38187 1220) (38219 1223) (38227 1241) (38229 1364) (42325 1419) (43349 1427)
(43605 1428) (43691 1597) (70997 1741) (75091 1765) (75093 1940) (76117 1969) (76373 1973) (76459 2207)
(84651 2296) (86699 2309) (87211 2311) (87339 2312) (87371 2317) (87379 2351) (87381 2584)
最后,对每一个输入的 N 值 (0 < N < 105,最多10个,时间限制是 2.0 秒) 用二分查找法查上面的表就行了。
Timus 1396. Maximum. Version 2 是同样的问题,但是要求 (0 < N < 1018) 且输入可多达 10000 个,时间限制是 1.0 秒。