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

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 20:25 Chauncey 閱讀(115) 評論(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>
            午夜精品99久久免费| 宅男66日本亚洲欧美视频| 一色屋精品视频在线看| 国产欧美日韩在线观看| 国产伦精品一区二区三区四区免费 | 国产精品社区| 国产伦精品一区二区三| 国产主播一区| 91久久精品久久国产性色也91| 亚洲国产99| 亚洲一区观看| 久久免费视频网| 最新国产乱人伦偷精品免费网站| 91久久精品一区二区别| 亚洲免费综合| 女同一区二区| 国产日韩欧美一区二区三区在线观看| 尤妮丝一区二区裸体视频| 99在线热播精品免费| 欧美一级电影久久| 欧美成人性网| 亚洲欧美成人网| 欧美va亚洲va国产综合| 国产欧美一区二区三区久久 | 国产精品地址| 激情综合网激情| 亚洲一区日韩| 欧美激情一区二区三区在线| 亚洲尤物精选| 欧美精品乱码久久久久久按摩| 国产乱码精品一区二区三| 亚洲免费不卡| 免费黄网站欧美| 亚洲专区一区| 欧美日韩亚洲一区二区三区在线观看| 国内揄拍国内精品久久| 亚洲主播在线观看| 最新成人在线| 久久综合久久综合九色| 国产精品美女久久久久久免费 | 亚洲视频福利| 美女日韩在线中文字幕| 国产日韩精品视频一区| 在线视频你懂得一区二区三区| 久久精品女人| 亚洲欧美国产毛片在线| 欧美午夜宅男影院| 一区二区av在线| 亚洲激情小视频| 久久亚洲综合网| 国外成人在线视频| 久久精品欧美日韩| 亚洲午夜av电影| 国产精品久久久久国产精品日日| 日韩亚洲国产精品| 亚洲国产婷婷| 欧美成人亚洲| 亚洲国产合集| 欧美+亚洲+精品+三区| 欧美一区二区大片| 国产一区在线看| 久久天天躁夜夜躁狠狠躁2022| 羞羞漫画18久久大片| 国产日韩欧美三区| 久久久青草青青国产亚洲免观| 欧美亚洲一区| 国产亚洲日本欧美韩国| 久久九九国产精品| 午夜在线精品偷拍| 一区二区三区在线免费视频| 男人插女人欧美| 美女在线一区二区| 日韩一级片网址| 亚洲视频一区二区| 国产一区二区精品在线观看| 美女脱光内衣内裤视频久久影院 | 亚洲网站在线播放| 国产日产亚洲精品| 久久夜色精品| 欧美激情亚洲激情| 亚洲一区视频| 久久久久久久久久久久久9999| 亚洲国产高清自拍| 在线综合+亚洲+欧美中文字幕| 国产啪精品视频| 麻豆视频一区二区| 欧美日本免费| 久久久精品国产99久久精品芒果| 久久一区二区三区av| 99re66热这里只有精品3直播 | 亚洲一区二区在线免费观看| 国产日韩欧美a| 另类尿喷潮videofree| 欧美激情小视频| 亚洲国产小视频| 亚洲精品一区久久久久久| 99精品福利视频| 国内精品久久久久久影视8| 亚洲高清久久网| 欧美人成在线视频| 久久精品人人做人人爽电影蜜月| 毛片一区二区三区| 欧美一级淫片aaaaaaa视频| 免费成人高清视频| 欧美一区二区在线播放| 久久综合九色| 久久精品国产精品亚洲综合| 欧美日韩大片| 欧美激情视频给我| 国产一区二区三区av电影| 亚洲精选大片| 亚洲精品国产精品国自产观看浪潮 | 午夜影院日韩| 欧美精品xxxxbbbb| 午夜精品福利视频| 欧美激情视频免费观看| 美乳少妇欧美精品| 国产精品午夜av在线| 亚洲精品乱码久久久久久日本蜜臀| 国产精品亚发布| 亚洲精品久久视频| 亚洲国产另类久久精品| 久久精品国产清自在天天线 | 欧美一区国产一区| 欧美aⅴ99久久黑人专区| 亚洲尤物在线| 欧美日精品一区视频| 欧美有码视频| 欧美日韩免费高清| 亚洲精品国产品国语在线app| 激情久久久久久久| 亚洲欧美中文在线视频| 性做久久久久久| 国产欧美精品va在线观看| 亚洲国产另类精品专区| 国产日韩精品入口| 欧美一区2区视频在线观看| 欧美一区日韩一区| 国产欧美一区二区在线观看| 午夜精彩视频在线观看不卡| 羞羞漫画18久久大片| 国产精品欧美日韩一区| 亚洲欧美日韩综合| 久久亚洲精品欧美| 在线国产欧美| 毛片av中文字幕一区二区| 美女任你摸久久| 亚洲国产欧美久久| 欧美国产大片| 亚洲欧洲视频| 亚洲女与黑人做爰| 欧美激情偷拍| 在线视频日韩精品| 久久精品一区中文字幕| 精久久久久久久久久久| 欧美成人综合网站| 免费久久99精品国产自| 毛片av中文字幕一区二区| 欧美高清在线播放| 国产精品99久久久久久久vr| 国产精品超碰97尤物18| 午夜在线视频一区二区区别| 欧美.www| 亚洲制服欧美中文字幕中文字幕| 国产亚洲欧美日韩精品| 久久综合伊人77777尤物| 亚洲巨乳在线| 久久久国产精品一区二区三区| 亚洲国产精品久久久久久女王| 欧美日韩国产综合一区二区| 亚洲性感激情| 欧美福利视频一区| 亚洲视频在线观看视频| 激情综合色综合久久| 欧美日韩直播| 久久综合图片| 亚洲欧美美女| 亚洲日本免费| 久久在精品线影院精品国产| 宅男精品视频| 亚洲第一毛片| 国产欧美日韩一区二区三区在线观看 | 激情欧美国产欧美| 欧美精品色综合| 性欧美办公室18xxxxhd| 亚洲精品久久久久久下一站| 久色成人在线| 欧美中文字幕第一页| 一本色道久久综合亚洲精品不 | 国产精品麻豆va在线播放| 久久精品女人| 亚洲欧美激情精品一区二区| 亚洲激情综合| 女同性一区二区三区人了人一 | 欧美日韩国产精品成人| 久久综合色影院| 久久精品视频导航| 午夜一区二区三区在线观看| 99亚洲伊人久久精品影院红桃| 欧美国产激情二区三区|