2008 Google Code jam 题目及解答(1)

Qualification Round Problem A:Saving the Universe

资格赛题目A:拯救宇宙

 

The urban legend goes that if you go to the Google homepage and search for "Google", the universe will implode. We have a secret to share... It is true! Please don't try it, or tell anyone. All right, maybe not. We are just kidding.
  有这么一个传说,如果你在Google的主页搜索"Google",那么宇宙将会爆炸。这是我们之间的秘密,并且是真的。请不要尝试这么做,或者告诉其他任何人。好吧,也许不是这样,我们仅仅是开个玩笑。

 

The same is not true for a universe far far away. In that universe, if you search on any search engine for that search engine's name, the universe does implode!

  对于很远很远的一个宇宙来说,这个就是真的。在那个宇宙中,如果你在任何搜索引擎中搜索该引擎的名字,那么这个宇宙就会爆炸。

 

To combat this, people came up with an interesting solution. All queries are pooled together. They are passed to a central system that decides which query goes to which search engine. The central system sends a series of queries to one search engine, and can switch to another at any time. Queries must be processed in the order they're received. The central system must never send a query to a search engine whose name matches the query. In order to reduce costs, the number of switches should be minimized.

  为了防止这种情况,人们提出了一个有趣的解决办法。把所有的查询集中起来并把他们传递给一个可以决定什么查询发送给什么搜索引擎的中心系统。这个中心系统发送一连串的查询给一个搜索引擎,并且可以在任何时候切换给另一个搜索引擎。查询必须按照他们被接收的顺序来处理。这个中心系统一定不能发送一个查询给和该查询同名的搜索引擎。为了节约成本,切换的次数应该最少。

 

Your task is to tell us how many times the central system will have to switch between search engines, assuming that we program it optimally.

  你的任务是告诉我们,假设我们编写最优的程序那么中心系统将必须切换搜索引擎多少次。

 

Input

输入

 

The first line of the input file contains the number of cases, N. N test cases follow.

  输入文件的第一行包括了总组数N,也就是说一共有N组数据。

 

Each case starts with the number S -- the number of search engines. The next S lines each contain the name of a search engine. Each search engine name is no more than one hundred characters long and contains only uppercase letters, lowercase letters, spaces, and numbers. There will not be two search engines with the same name.

  每组数据以数字S(搜索引擎的总数)开头。在接下来的S行中,每一行包括了一个搜索引擎的名字。每一个引擎的名字都不会超过100个字符的长度,并且只含有大写字母、小写字母、空格和数字,也不会有两个搜索引擎拥有相同的名字。

 

The following line contains a number Q -- the number of incoming queries. The next Q lines will each contain a query. Each query will be the name of a search engine in the case.

  接下来的一行包括了数字Q——接收到的查询的数目。之后的Q行都包含一个查询。每一个查询都将是该组其中一个搜索引擎的名字。

 

Output

输出

For each input case, you should output:

对于每一组输入,你将(按如下格式)输出:

Case #X: Y

where X is the number of the test case and Y is the number of search engine switches. Do not count the initial choice of a search engine as a switch.

  其中X是当前组的标号,Y是搜索引擎的切换次数。不要把初始选择一个搜索引擎也当作切换来计数。

 

Limits

限制

0 < N ≤ 20

Small dataset (小数据集)

2 ≤ S ≤ 10

0 ≤ Q ≤ 100

Large dataset (大数据集)

2 ≤ S ≤ 100

0 ≤ Q ≤ 1000

 

Sample

例子


Input

Output
2
5
Yeehaw
NSM
Dont Ask
B9
Googol
10
Yeehaw
Yeehaw
Googol
B9
Googol
NSM
B9
NSM
Dont Ask
Googol
5
Yeehaw
NSM
Dont Ask
B9
Googol
7
Googol
Dont Ask
NSM
NSM
Yeehaw
Yeehaw
Googol

Case #1: 1
Case #2: 0

 

 

In the first case, one possible solution is to start by using Dont Ask, and switch to NSM after query number 8.

  在第一组数据中,一个可行的解法是开始时使用Dont Ask,然后到第8个查询之后切换到NSM。


For the second case, you can use B9, and not need to make any switches.

  对于第二组数据,你可以使用B9,并且不需要切换。


 

题目浅析:

  既然题目要求的是求切换搜索引擎的次数最少,实际上是要求每次切换处理的查询最多。可以设置一个标志数组用于存放所有的搜索引擎名称,每当遇到一个查询就将与该查询同名的引擎从标志数组中删除,直到这个数组只剩下一个搜索引擎,那么这个搜索引擎就是下一次要切换到的引擎,并且切换次数加1。这个算法可能不是最优的算法,但是是可行的算法。Google codejam不像ACM/ICPC对算法的效率要求那么严格,其更倾向于结果的正确。以下是C#实现的解题代码。

 

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.IO;
 5
 6namespace SavingTheUniverse
 7{
 8    class Program
 9    {
10        static void Main(string[] args)
11        {
12            //用于存放搜索引擎名称
13            System.Collections.Generic.List<string> engines = new List<string>(100);
14            //作为搜索引擎的标志数组
15            System.Collections.Generic.List<string> enginesFlag = new List<string>(100);
16            //消息队列
17            System.Collections.Generic.Queue<string> queries = new Queue<string>(1000); 
18            StreamReader sr = new StreamReader("A-large-practice.in", Encoding.Default);
19            StreamWriter sw = new StreamWriter("A-large-practice.txt"false, Encoding.Default);
20            
21            int cases = int.Parse(sr.ReadLine());
22
23            for (int i = 1; i <= cases; ++i)  
24            {
25                //处理每组数据前做好准备工作
26                engines.Clear();
27                enginesFlag.Clear();
28                queries.Clear();
29                int switchCount = 0;
30
31                //将搜索引擎名称读入内存中
32                int enginesNum = int.Parse(sr.ReadLine());
33                for (int j = 0; j < enginesNum; ++j)
34                {
35                    engines.Add(sr.ReadLine());
36                }

37                enginesFlag.AddRange(engines);
38
39                //将查询名称读入内存中
40                int queriesNum = int.Parse(sr.ReadLine());
41                for (int j = 0; j < queriesNum; ++j)
42                {
43                    queries.Enqueue(sr.ReadLine());    
44                }

45
46                while (queries.Count > 0)
47                {
48                    string current = queries.Dequeue(); //一条消息出队
49                    if (enginesFlag.Contains(current))
50                    {
51                        if (enginesFlag.Count == 1//标志列表只剩下最后一个搜索引擎
52                        {
53                            enginesFlag.Clear();
54                            enginesFlag.AddRange(engines);
55                            switchCount++//切换次数加1
56                        }

57                        enginesFlag.Remove(current);
58                    }

59                }

60
61                sw.WriteLine("Case #" + i + "" + switchCount); //输出
62            }

63            sr.Close();
64            sw.Close();
65        }

66    }

67}

posted @ 2008-08-08 15:32  YangQ  阅读(4257)  评论(0编辑  收藏  举报