银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
Timus 1219. Symbolic Sequence 要求输出满足给定条件的一百万个小写拉丁字母。

1219. Symbolic Sequence

Time Limit: 1.0 second
Memory Limit: 16 MB

Your program is to output a sequence of 1 000 000 lowercase Latin letters. This sequence should satisfy the following restrictions:
  • Every letter occurs not more than 40 000 times in the sequence;
  • Every possible subsequence with two letters length occurs not more than 2 000 times;
  • Every possible subsequence with three letters length occurs not more than 100 times;

Input

For this problem no input is provided.

Output

In a single line of the output write some sequence, which satisfies the properties described above.

Problem Author: Pavel Atnashev, Leonid Volkov, text by Pavel Atnashev
Problem Source: The Seventh Ural State University collegiate programming contest

答案如下:

 1 using System;
 2 
 3 namespace Skyiv.Ben.Timus
 4 {
 5   // http://acm.timus.ru/problem.aspx?space=1&num=1219
 6   sealed class T1219a
 7   {
 8     static void Main()
 9     {
10       for (int n = 1000000; ; )
11         for (int i = 0; i < 26; i++)
12           for (int j = 0; j < 26; j++)
13             for (int k = 0; k < 26; k++)
14             {
15               if (n-- > 0) Console.Write((char)('a' + i));
16               if (n-- > 0) Console.Write((char)('a' + j));
17               if (n-- > 0) Console.Write((char)('a' + k));
18               else return;
19             }
20     }
21   }
22 }

这道题目是要求输出满足给定条件的一百万个小写拉丁字母,条件如下:

  • 每个字母出现的次数不得多于 40,000 次
  • 每个两字母序列出现的次数不得多于 2,000 次
  • 每个三字母序列出现的次数不得多于 100 次

本程序的算法也很简单,就是重复输出以下序列直到满一百万个字母:

aaa aab aac ... zzz

我们知道,以上序列的长度是 263 * 3 = 52,728,而 52,728 * 19 = 1,001,832。所以这个序列重复次数不会超过 19 次。

稍微改变一下,使用两个 StringBuilder,sb1 存储“aaa aab aac ... zzz”串,sb2 就是 sb1 重复 19 次,然后截短到一百万个字符,最后直接用 Console.Write(sb2) 输出。程序如下:

 1 using System;
 2 using System.Text;
 3 
 4 namespace Skyiv.Ben.Timus
 5 {
 6   // http://acm.timus.ru/problem.aspx?space=1&num=1219
 7   sealed class T1219b
 8   {
 9     static void Main()
10     {
11       StringBuilder sb1 = new StringBuilder(26 * 26 * 26 * 3);
12       for (int i = 0; i < 26; i++)
13         for (int j = 0; j < 26; j++)
14           for (int k = 0; k < 26; k++)
15           {
16             sb1.Append((char)('a' + i));
17             sb1.Append((char)('a' + j));
18             sb1.Append((char)('a' + k));
19           }
20       StringBuilder sb2 = new StringBuilder(sb1.Length * 19);
21       for (int i = 0; i < 19; i++) sb2.Append(sb1);
22       sb2.Length = 1000000;
23       Console.Write(sb2);
24     }
25   }
26 }

下面是运行结果

上图中,ID 为 2145580 的记录就是后面一个 C# 程序的运行结果。可以看到,运行时间(0.093 秒)减少到前面一个 C# 程序(ID 为 2144769)的十分之一,但内存占用(4,054 KB)增加到原来的四倍。

上图中,ID 为 2144784 ( 运行时间: 0.062 秒,内存占用: 181 KB ) 的记录对应本程序的 C++ 语言版本,如下:

 1 // http://acm.timus.ru/problem.aspx?space=1&num=1219
 2 #include <iostream>
 3 
 4 int main()
 5 {
 6   for (int n = 1000000; ; )
 7     for (int i = 0; i < 26; i++)
 8       for (int j = 0; j < 26; j++)
 9         for (int k = 0; k < 26; k++)
10         {
11           if (n-- > 0) std::cout << (char)('a' + i);
12           if (n-- > 0) std::cout << (char)('a' + j);
13           if (n-- > 0) std::cout << (char)('a' + k);
14           else return 0;
15         }
16 }

而 ID 为 2144790 ( 运行时间: 0.015 秒,内存占用: 125 KB ) 的记录对应本程序的 C 语言版本,如下:

 1 // http://acm.timus.ru/problem.aspx?space=1&num=1219
 2 #include <stdio.h>
 3 
 4 int main()
 5 {
 6   int i, j, k, n = 1000000;
 7   for (; ; )
 8     for (i = 0; i < 26; i++)
 9       for (j = 0; j < 26; j++)
10         for (k = 0; k < 26; k++)
11         {
12           if (n-- > 0) putchar('a' + i);
13           if (n-- > 0) putchar('a' + j);
14           if (n-- > 0) putchar('a' + k);
15           else return 0;
16         }
17 }
posted on 2008-07-01 23:41  银河  阅读(934)  评论(0编辑  收藏  举报