青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Google code jam 2008 QR - Saving the Universe

Problem

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.

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.

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.

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.

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.

 

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.
For the second case, you can use B9, and not need to make any switches.


Analysis

The first task in the new Google Code Jam is about, no surprise, search engines, and also, the grandiose feat of saving the universe in a parsimonious way. However, putting all the fancies aside, the problem itself is easy.

List all queries one by one, and break them up into segments. Each segment will be an interval where we use one search engine, and when we cross from one segment to another we will switch the search engine we use. What can you say about each segment? Well, one thing for sure is:

Never ever ever have all S different search engines appear as queries in one segment. (*)
Why is this? Because if all S names appeared in one segment, then any search engine used for that segment will encounter at least one query that is the same as its name, thus exploding the universe!

 

Working in the opposite direction, (*) is all we need to achieve; as long as you can partition the list of queries into such segments, it corresponds to a plan of saving the universe. You don't even care about which engine is used for one segment; any engine not appearing as a query on that segment will do. However, you might sometimes pick the same engine for two consecutive segments, laughing at yourself when you realize it; why don't I just join the two segments into one? Because your task is to use as few segments as possible, it is obvious that you want to make each segment as long as possible.

This leads to the greedy solution: Starting from the first query, add one query at a time to the current segment until the names of all S search engines have been encountered. Then we continue this process in a new segment until all queries are processed.

Sample code in C++, where st is the set of queries in the current segment, q is the next query, and count is the number of switches.

st.clear();
count = 0;
for (int i=0; i<Q; i++) {
getline(cin, q);
if (st.find(q) == st.end()) {
if (st.size() == S-1) {
st.clear();
count++;
}
st.insert(q);
}
}
If st is a hashset, you expect the solution run in O(n) time. Note that this solution uses the fact that each query will be a search engine name and so we can ignore the list of names provided in the input.

 

Let us justify that the greedy approach always gives the optimal answer. Think of the procedure as Q steps, and we want to show that, for each i, there is (at least) one optimal choice which agrees with us on the first i steps. We do this inductively for i = 0, then i = 1, and so on. The proposition for i = Q when proven true will imply that our algorithm is correct.

So, the key points in the inductive step i:

  1. If adding the next query will explode the universe, we must start a new segment. Any optimal choice agrees with us for the first (i-1) steps must also do that.
  2. If adding the next query will not explode the universe, we do not start a new segment. We know there is an optimal solution R agreed with us for (i-1) steps. Even if in R a new segment is started at step i, we can modify it a little bit. Let R' be the plan that agrees with R, but instead of starting a new segment on the i-th step, we delay this to the (i+1)st. It is clear that R' will also make the universe safe, and has no more switches than R does. So, R' is also an optimal solution, and agrees with our choice for the first i steps.

 

The similar lines of justifications work for many greedy algorithms, including the well beloved minimum spanning trees.
 
Another DP Solution:

Def. Cost[k][i] as the min switches
when k queries come and current search engine is i

0<=i<=S
0<=k<=Q

1. Optimal: if i!=id[k]: Cost[k][i]=min{..., Cost[k-1][i-2]+1, Cost[k-1][i-1]+1, Cost[k-1][i], Cost[k-1][i+1]+1, Cost[k-1][i+2]+1,...}

    else: Cost[k][i]=min{..., Cost[k-1][i-2]+1, Cost[k-1][i-1]+1, Cost[k-1][i+1]+1, Cost[k-1][i+2]+1,...}

2. Init: Cost[0][i]=0


Source Code
#include <hash_set>
#include 
<iostream>

using namespace std;

#define Rep(i,n) for (int i(0),_n(n); i<_n; ++i)

int main()
{
    
int T;
    
//freopen("..\\s.in","r",stdin);
    
//freopen("..\\s.out","w",stdout);
    scanf("%d"&T);
    Rep(t, T) 
{
        
int S;
        scanf(
"%d"&S);
        
string q;
        getline(cin, q);
//a unread '\n' in scanf
        Rep(i, S) {
            getline(cin, q);
        }

        
int Q;
        scanf(
"%d"&Q);
        getline(cin, q);

        stdext::hash_set
<string> st;
        
int count = 0;
        Rep(i, Q) 
{
            getline(cin, q);
            
if (st.find(q) == st.end()) {
                
if (st.size() == S-1{
                    st.clear();
                    count
++;
                }

                st.insert(q);
            }

        }

        
        printf(
"Case #%d: %d\n", t+1, count);
    }

}

posted on 2009-08-12 21:20 Chauncey 閱讀(320) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導(dǎo)航

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

統(tǒng)計(jì)

常用鏈接

留言簿

隨筆檔案(4)

文章檔案(3)

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲第一页自拍| 欧美激情一区二区三区在线视频观看| 久久久国产精品一区二区三区| 一本色道久久88亚洲综合88| 久久久精品国产免大香伊| 亚洲欧美国产77777| 欧美精品黄色| 亚洲国产精品va| 一区二区在线视频| 性欧美大战久久久久久久久| 亚洲一区二区三区视频| 欧美日韩国产综合久久| 亚洲国产色一区| 最新成人av在线| 免费影视亚洲| 欧美成人免费在线视频| 在线日韩成人| 蜜臀91精品一区二区三区| 欧美成人按摩| 亚洲激情女人| 欧美国产精品中文字幕| 最新日韩精品| 9i看片成人免费高清| 欧美乱在线观看| 一区二区三区免费网站| 亚洲资源av| 国产日韩欧美综合精品| 久久国产黑丝| 欧美高清在线精品一区| 亚洲啪啪91| 欧美日韩黄视频| 亚洲一区激情| 久久婷婷蜜乳一本欲蜜臀| 在线精品国产成人综合| 欧美成人精品一区二区三区| 亚洲精品日本| 性色av一区二区三区在线观看| 国产视频一区在线| 久久影视三级福利片| 亚洲国产精品传媒在线观看 | 一区二区三区免费网站| 午夜精品免费在线| 在线观看国产日韩| 欧美精品一区二区三区一线天视频 | 中日韩在线视频| 国产精品日韩电影| 久久精品二区三区| 最新国产成人在线观看| 欧美夜福利tv在线| 亚洲国产小视频| 国产精品久久网站| 久久久视频精品| 日韩网站在线| 久久久久久亚洲精品杨幂换脸| 91久久精品一区二区三区| 欧美日本高清视频| 午夜精品视频在线| 亚洲国产一区二区三区a毛片| 亚洲男人的天堂在线观看| 狠狠色狠狠色综合人人| 欧美日韩亚洲一区二区三区| 久久国产精品电影| 99国内精品| 欧美成人一品| 欧美在线观看你懂的| 亚洲精品你懂的| 国产日韩欧美日韩大片| 欧美**人妖| 久久精品九九| 亚洲一区二区三区免费视频| 欧美电影在线播放| 久久精品国产第一区二区三区最新章节 | 久久av一区| 一个人看的www久久| 国产一区二区三区在线观看免费| 欧美日韩精品免费观看视一区二区 | 欧美精品一卡二卡| 久久另类ts人妖一区二区| 亚洲视频久久| 亚洲国产天堂久久综合网| 久热综合在线亚洲精品| 午夜日韩在线| 亚洲一区精品电影| 亚洲最新在线视频| 亚洲激情视频网站| 激情成人av| 国产一区二区三区日韩| 国产精品视频99| 国产精品theporn88| 欧美激情综合五月色丁香小说| 久久精品国产v日韩v亚洲 | 在线亚洲免费视频| 亚洲人成网站777色婷婷| 欧美电影在线观看完整版| 久久久亚洲午夜电影| 久久国产精品毛片| 久久精品国产在热久久| 欧美亚洲系列| 欧美一区二区三区视频在线| 亚洲一区精彩视频| 亚洲综合日韩在线| 午夜精品久久久久久| 亚洲欧美日韩国产一区| 亚洲欧美日韩一区二区| 亚洲免费中文字幕| 新狼窝色av性久久久久久| 午夜在线成人av| 久久精品国产久精国产思思| 久久av最新网址| 久久久亚洲影院你懂的| 麻豆精品精品国产自在97香蕉| 久久久久久一区| 美女精品在线| 亚洲国产欧美在线| 日韩一区二区久久| 亚洲永久免费观看| 欧美一区二区在线播放| 久久久久女教师免费一区| 久久人人九九| 欧美人与禽猛交乱配| 欧美香蕉视频| 国产一区二区电影在线观看 | 久久电影一区| 久久男人av资源网站| 欧美aaaaaaaa牛牛影院| 欧美日韩国产综合视频在线观看中文 | 久久精品视频一| 欧美成人国产| 国产精品久久久久久久久久免费看 | 国产精品入口福利| 狠狠久久亚洲欧美| 亚洲精品综合| 欧美影院成年免费版| 欧美成年人网| 一区二区欧美日韩视频| 久久精品国产免费看久久精品| 欧美1区2区视频| 国产精品视频1区| 亚洲国产一区二区在线| 亚洲在线视频观看| 免费的成人av| 在线视频你懂得一区| 久久精品视频免费播放| 欧美精品一区二区三区一线天视频| 国产精品免费一区二区三区观看| 今天的高清视频免费播放成人| 99精品久久| 久久这里有精品视频| 亚洲久色影视| 老色鬼久久亚洲一区二区| 国产精品扒开腿做爽爽爽软件| 在线成人激情黄色| 亚洲欧美视频在线观看视频| 欧美激情一区二区三区| 亚洲婷婷综合久久一本伊一区| 老牛嫩草一区二区三区日本| 国产精品一区一区| 一区二区黄色| 欧美高清在线视频| 欧美诱惑福利视频| 欧美午夜在线一二页| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久久综合激的五月天| 国产精品美女www爽爽爽| 亚洲激情精品| 久久久人人人| 午夜一级久久| 国产精品国产成人国产三级| 亚洲人成人77777线观看| 久久久噜噜噜久久人人看| 中日韩美女免费视频网址在线观看| 蜜桃av一区| 在线播放中文一区| 久久久激情视频| 亚洲欧美一区二区三区在线| 欧美亚州韩日在线看免费版国语版| 亚洲精品久久久蜜桃| 欧美成人国产| 久热爱精品视频线路一| 伊人男人综合视频网| 久久漫画官网| 久久久777| 伊人成人在线| 免费亚洲一区| 老牛国产精品一区的观看方式| 依依成人综合视频| 美女久久网站| 免费亚洲电影在线观看| 亚洲欧洲一区二区三区在线观看| 欧美a级在线| 另类人畜视频在线| 亚洲国产日韩欧美在线动漫| 欧美成黄导航| 欧美成人小视频| 日韩一区二区电影网| 亚洲免费高清| 国产精品久久777777毛茸茸| 亚洲在线成人| 性一交一乱一区二区洋洋av| 国产一区二区三区在线观看网站 |