资格赛:拯救宇宙

Qualification RoundProblem A:Saving the Universe

资格赛题目A:拯救宇宙

 

The urban legend goes that if you go to the Google homepage andsearch for "Google", the universe will implode. We have a secret toshare... It is true! Please don't try it, or tellanyone. All right, maybe not. We are justkidding. 
  有这么一个传说,如果你在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. Allqueries are pooled together. They are passed to a central systemthat decides which query goes to which search engine. The centralsystem sends a series of queries to one search engine, and canswitch to another at any time. Queries must beprocessed in the order they're received. Thecentral system must never send a query to a search engine whosename matches the query. In order to reduce costs, the number ofswitches should be minimized.

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

 

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

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

 

Input

输入

 

The first line of the input file contains the number ofcases, NN testcases follow.

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

 

Each case starts with the number S -- thenumber of search engines. The next S lines eachcontain the name of a search engine. Each search engine name is nomore than one hundred characters long and contains only uppercaseletters, lowercase letters, spaces, and numbers. There will not betwo search engines with the same name.

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

 

The following line contains anumber Q --the number of incoming queries. Thenext Q lines willeach contain a query. Each query will be thename of a search engine in the case.

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

 

Output

输出

For each input case, you should output:

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

Case #X: Y

where X is thenumber of the test case and Y is thenumber of search engine switches. Do not count the initial choiceof 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 startby using Dont Ask, and switch to NSM after querynumber 8.

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


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

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



--------------------------------------------------------------------------------------------

我是在http://www.cnblogs.com/roovent/archive/2008/08/08/1263802.html

这篇博文看见这题的,看着有意思就试着写了下(java版),原博客方法是先写出这所有引擎,然后每次输入一个query,就删去一个引擎,直到最后一个的时候,表明我一开始就用这个最后剩下的引擎的话,相对来说可以走最远的路,然后转向另外的引擎时也采用同样的方法,具体介绍见原博客。

我说下我的思路:我先记录一个map。记录所有的搜索引擎,然后遍历query,记录所有搜索引擎出现的次数,记录在map里(map引擎名字-引擎作为query次数) 。

然后从头开始,

step1:挑选query次数最少的作为第一个引擎(如果恰好是第一个,换第二少的)

step2:每搜索一个引擎,就相应的引擎次数减少,map.get(EngineName)--,,如果发现当前query和引擎名字相同,则再找出现在次数最少的(如果恰好和下一个query相同,换第二少的,类似第一次情况

step3:找出转换次数

==========================

与原博客相比,方法思路应该是类似的

突发奇想。。。。其实我的方法很垃圾。。。。本方法应该可以进行一个训练(假设搜索query遵循了某种概率分布),找出次数最低的,一开始就用这个,然后按顺序


---------------------------------------code-----------------------------------

package com.ylf;


importjava.io.BufferedReader;

import java.io.File;

importjava.io.FileInputStream;

import java.io.FileReader;

import java.io.IOException;

importjava.io.InputStreamReader;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Set;

importjava.util.concurrent.ArrayBlockingQueue;


 

public class SaveUniversal{


 

//记录搜索引擎出现次数

private HashMap<String,Integer> se = new HashMap<String,Integer>();

privateArrayList<String> qu = newArrayList<String>();

private int caseN = 0;

private int engineN = 0;

private int queryN = 0;

 

public static int switchN =0;

 

public static void main(String[] args){

 

SaveUniversal su = newSaveUniversal();

su.solve("src/data/search_engines_queries");

}

 

public void solve(StringfileName){

try {

 

File file = newFile(fileName);

FileReader fr = newFileReader(file);

BufferedReader br = newBufferedReader(fr);

 

String line = "";

//读取case total number

caseN =Integer.parseInt(br.readLine());

 

for(int i =0;i<caseN;i++){

//读取current case : engines totalnumber

engineN =Integer.parseInt(br.readLine());

for(intj=0;j<engineN;j++){

se.put(br.readLine(),0);//把引擎读入

}

 

//读取current case: query totalnumber

queryN = Integer.parseInt(br.readLine());

for(intj=0;j<queryN;j++){

String query =br.readLine();

Integer q =(Integer)se.get(query);

q++;

se.put(query, q);

qu.add(query);

}

 

//开始找出最小转换次数

String minEngine =getMin(se);

System.out.println("first use\""+minEngine+"\"");

for(intj=0;j<qu.size();j++){

String query = qu.get(j);

if(minEngine.equals(query)){

System.out.print("switch from\""+minEngine+"\"("+j+")");

minEngine = getMin(se);

if(minEngine.equals(query)){

//这里找出第二小的

Integer temp =se.get(minEngine);

String strEng = minEngine;

se.remove(minEngine);

minEngine = getMin(se);

se.put(strEng, temp);

}

if(j!=0){

switchN++;

}

System.out.println("  to\""+minEngine+"\"");

}

Integer q =(Integer)se.get(query);

q--;

se.put(query, q);

}

 

System.out.println("#case"+i+":"+switchN);

switchN=0;

se.clear();

qu.clear();

}

 

} catch (IOException e) {

e.printStackTrace();

}

}

 

 

public StringgetMin(HashMap<String,Integer>map){

Set<String>keys = map.keySet();

Iterator<String> it =keys.iterator();

int min=1000;

String str = "";

while(it.hasNext()){

String key =(String)it.next();

if(map.get(key) <min){

min = map.get(key);

str = key;

}

}

return str;

}


public voidprintSe(HashMap<String,Integer>map){

Set<String>keys = map.keySet();

Iterator<String> it =keys.iterator();

while(it.hasNext()){

String key =(String)it.next();

System.out.println("key="+key+" ;value="+map.get(key));

}

}

}

----------------------------输出-------------------这里我用原始数据
first use "Dont Ask"
switch from "Dont Ask"(8)   to "B9"
#case0:1
first use "B9"
#case1:0
-------------------------------------------------
输出当然有些多余的,我是测试用的

你可能感兴趣的:(拯救宇宙)