银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
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

inputoutput
5
10
0
3
4

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 == 0break;
20         writer.WriteLine(((n < 3? 1 : GetMaximum(n, 311)));
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 == 0break;
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 秒。

posted on 2008-06-19 11:53  银河  阅读(988)  评论(3编辑  收藏  举报