Timus 1079. Maximum 要求输出指定数列中的最大值。
Problem Author: Emil Kelevedzhiev
Problem Source: Winter Mathematical Festival Varna '2001 Informatics Tournament
( 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)
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
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
input | output |
---|---|
5 10 0 |
3 4 |
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 }
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 }
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 秒。