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

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 閱讀(318) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導航

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

統計

常用鏈接

留言簿

隨筆檔案(4)

文章檔案(3)

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            99riav久久精品riav| 欧美激情一区在线观看| 欧美r片在线| 久久久久一区二区三区| 性高湖久久久久久久久| 国产精品99久久久久久久久| 久久国产免费| 亚洲欧美综合精品久久成人| 亚洲欧美日韩国产中文在线| 欧美在线播放视频| 久久天天狠狠| 欧美国产一区二区| 亚洲美女在线一区| 亚洲一区二区精品| 性久久久久久| 毛片基地黄久久久久久天堂| 欧美精品久久99| 国产区精品视频| 亚洲福利视频网站| 亚洲一区一卡| 欧美激情bt| 亚洲综合好骚| 欧美xart系列高清| 国产欧美精品一区二区三区介绍 | 一区二区三区在线观看国产| 91久久精品www人人做人人爽| 一区二区高清视频在线观看| 欧美专区亚洲专区| 亚洲精品在线观看免费| 久久免费国产精品| 国产精品剧情在线亚洲| 亚洲黄色一区二区三区| 欧美中文字幕不卡| 亚洲精选在线观看| 久色婷婷小香蕉久久| 国产伦精品一区二区三| 99riav久久精品riav| 免费成人网www| 午夜视频一区在线观看| 欧美日韩一区二区三区视频| 1024精品一区二区三区| 欧美专区在线播放| 中文欧美在线视频| 欧美区日韩区| 亚洲精品国久久99热| 久久三级视频| 亚洲自拍偷拍色片视频| 欧美日韩一区二区视频在线| 亚洲激情在线| 欧美a级片一区| 久久九九全国免费精品观看| 国产精品日本| 亚洲免费在线电影| 99综合精品| 欧美日韩国产精品专区| 日韩亚洲一区在线播放| 亚洲高清久久网| 欧美影院成人| 国产一区日韩二区欧美三区| 欧美一区二区三区喷汁尤物| 亚洲精品一区二区三区99| 久久疯狂做爰流白浆xx| 在线观看视频一区二区| 9l视频自拍蝌蚪9l视频成人| 你懂的国产精品| 久久亚洲不卡| 亚洲国产高清一区| 亚洲福利av| 欧美精品久久99久久在免费线| 亚洲精品欧美激情| 亚洲美女区一区| 国产精品福利网站| 亚洲色图在线视频| 亚洲午夜在线观看| 国产欧美一区二区三区久久人妖| 校园春色国产精品| 欧美一区激情| 亚洲高清在线视频| 亚洲欧洲精品一区二区三区| 欧美国产一区二区| 亚洲女人天堂av| 亚洲欧美综合国产精品一区| 国产一区二区三区在线观看免费视频 | 91久久久国产精品| 亚洲国产91精品在线观看| 欧美片在线观看| 欧美有码在线视频| 久久男女视频| 99精品久久久| 亚洲一区国产精品| 在线观看成人小视频| 亚洲国产小视频| 国产精品丝袜xxxxxxx| 免费一级欧美片在线播放| 欧美久久久久久| 久久成人人人人精品欧| 另类天堂av| 午夜精品久久久久久久久久久| 久久精品国产综合精品| 亚洲无限av看| 欧美伊人久久| 亚洲免费影视| 欧美激情精品久久久久久蜜臀 | 国产精品一区久久久| 麻豆成人小视频| 欧美日韩午夜视频在线观看| 久久久久9999亚洲精品| 欧美日韩国产亚洲一区| 久久字幕精品一区| 国产精品国产自产拍高清av王其| 久久人体大胆视频| 国产精品美女久久| 亚洲三级电影全部在线观看高清| 国产性猛交xxxx免费看久久| 亚洲美女性视频| 亚洲电影在线播放| 亚洲精品日韩欧美| 欧美激情精品久久久久久黑人| 国产精品丝袜91| av不卡免费看| 亚洲精品久久久久久久久| 欧美一区二区三区男人的天堂| 一区二区三区欧美在线观看| 女女同性精品视频| 免费国产一区二区| 国内精品久久久久久影视8| 99精品国产在热久久婷婷| 亚洲国产精品成人综合色在线婷婷 | 久久精品国产精品亚洲精品| 亚洲欧美另类在线观看| 欧美区一区二区三区| 亚洲国产另类久久久精品极度| 一区二区三区在线观看视频| 欧美影院久久久| 久久国产一区二区| 国产欧美一区二区精品婷婷| 午夜国产不卡在线观看视频| 午夜精品视频一区| 国产精品区一区二区三区| 亚洲一区二区三区四区五区午夜| 亚洲一区二区精品| 国产精品你懂的在线欣赏| 亚洲一区二区在线视频 | 亚洲国产cao| 久久午夜av| 暖暖成人免费视频| 最新国产成人av网站网址麻豆| 免费视频一区| 亚洲三级性片| 亚洲免费在线| 国产一区二区看久久| 久久青草久久| 亚洲高清av在线| 宅男噜噜噜66一区二区| 国产精品国产三级国产a| 中文在线资源观看网站视频免费不卡| 亚洲免费在线视频| 国产主播一区二区三区| 久久一区二区三区国产精品| 亚洲第一区在线| 亚洲自拍偷拍麻豆| 国产一区二区视频在线观看| 快射av在线播放一区| 亚洲精品一区在线| 欧美一区二区三区在线观看视频| 韩国一区二区三区在线观看| 麻豆成人在线播放| 亚洲天堂av电影| 免费不卡欧美自拍视频| 一区二区欧美国产| 狠狠色狠狠色综合日日91app| 欧美国产成人在线| 亚洲欧美中文另类| 亚洲欧洲日产国产网站| 欧美一级视频精品观看| 亚洲激情视频在线播放| 国产精品区一区二区三区| 美女精品在线观看| 亚洲欧美中文日韩在线| 亚洲精品激情| 久久综合一区| 亚洲精品精选| 亚洲黑丝在线| 国产老肥熟一区二区三区| 久久亚洲免费| 羞羞视频在线观看欧美| 亚洲日本一区二区| 久久人91精品久久久久久不卡| 亚洲午夜精品一区二区三区他趣| 伊人春色精品| 国产日本欧美一区二区三区| 欧美日本国产精品| 久久综合一区二区| 久久精品人人做人人爽| 亚洲一区二区黄色| 99热在线精品观看| 亚洲国内精品| 欧美好吊妞视频| 免费在线成人av| 久久久精品动漫|