1219. Symbolic Sequence
Time Limit: 1.0 second
Memory Limit: 16 MB
- 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 AtnashevProblem Source: The Seventh Ural State University collegiate programming contest
答案如下:
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) 输出。程序如下:
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++ 语言版本,如下:
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 语言版本,如下:
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 }