谷歌kickstart 2018 round A

这一轮比较简单,只要拿到51分就可以去面试了。也就是第一题和后两题的第一问。

Problem1 Even Digits (8pts, 15pts) 

Supervin has a unique calculator. This calculator only has a display, a plus button, and a minus button. Currently, the integer N is displayed on the calculator display.

Pressing the plus button increases the current number displayed on the calculator display by 1. Similarly, pressing the minus button decreases the current number displayed on the calculator display by 1. The calculator does not display any leading zeros. For example, if 100 is displayed on the calculator display, pressing the minus button once will cause the calculator to display 99.

Supervin does not like odd digits, because he thinks they are "odd". Therefore, he wants to display an integer with only even digits in its decimal representation, using only the calculator buttons. Since the calculator is a bit old and the buttons are hard to press, he wants to use a minimal number of button presses.

Please help Supervin to determine the minimum number of button presses to make the calculator display an integer with no odd digits.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each begins with one line containing an integer N: the integer initially displayed on Supervin's calculator.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and yis the minimum number of button presses, as described above.

Limits

1 ≤ T ≤ 100.
Time limit: 20 seconds per test set.
Memory limit: 1GB.

Small dataset (Test set 1 - Visible)

1 ≤ N ≤ 105.

Large dataset (Test set 2 - Hidden)

1 ≤ N ≤ 1016.

Sample


Input 
 

Output 
 
4
42
11
1
2018

  
Case #1: 0
Case #2: 3
Case #3: 1
Case #4: 2

  

In Sample Case #1, the integer initially displayed on the calculator has no odd digits, so no button presses are needed.

In Sample Case #2, pressing the minus button three times will cause the calculator to display 8. There is no way to satisfy the requirements with fewer than three button presses.

In Sample Case #3, either pressing the minus button once (causing the calculator to display 0) or pressing the plus button once will cause the calculator to display an integer without an odd digit.

In Sample Case #4, pressing the plus button twice will cause the calculator to display 2020. There is no way to satisfy the requirements with fewer than two button presses.

  • 思路:
    • 找两个比当前数大的和小的符合规则的数。然后对比哪一个离当前数比较近就可以。
    • 先从低位开始找第一个奇数
    • 小的是把这个奇数减一,后面为全都填8
    • 大的是把这个数加一,后面的全填0。注意没有必要处理进位的问题。一进位就大了一个数量级的差距。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

long long calculate(long long n) {
    long long tmp = n;
    vector<int> numbers;
    while(tmp) {
        numbers.push_back(tmp % 10);
        tmp /= 10;
    }
    reverse(numbers.begin(), numbers.end());
    int odd_index = -1;
    for(int i = 0; i < numbers.size(); i++) {
        if(numbers[i] % 2 != 0) {
            odd_index = i;
            break;
        }
    }
    if (odd_index == -1) {
        return 0;
    }
    long long remain = 0;
    for(int i = odd_index; i < numbers.size(); i++) {
        remain = remain * 10 + numbers[i];
    }

    long long smaller_one = numbers[odd_index] - 1;
    for (int i = odd_index + 1; i < numbers.size(); i++) {
        smaller_one = smaller_one * 10 + 8;
    }

    long long larger_one = numbers[odd_index] + 1;
    if (numbers[odd_index] == 9) {
        // tricky,这个地方不用管,因为一进位就大了一个数量级,就没必要比了
        return remain - smaller_one;
    } else {
        for(int i = odd_index + 1; i < numbers.size(); i++) {
            larger_one *= 10;
        }
    }
    return min(remain - smaller_one, larger_one - remain);
}

int main() {
    int t;
    scanf("%d", &t);
    for(int i = 0; i < t; i ++){
        long long n, result;
        scanf("%lld", &n);
        result = calculate(n);
        printf("Case #%d: %lld\n", i + 1, result);
    }
    return 0;
}

Problem2 Lucky Dip (10pts, 19pts)

You are participating in the Grand Kickstart Lucky Dip with many fantastic and amazing prizes (and some not so good ones)!

In this Lucky Dip, there is a bag with N items. The i-th item in the bag has value Vi. You will put your hand into the bag and draw one item at random; all items in the bag have an equal probability of being chosen. The organizers want contestants to feel that they have some element of choice, so after you draw an item, you can either keep it, or "redip" by returning it to the bag and drawing again. (Note that the returned item is now just as likely to be chosen as any of the other items in the bag.) You may only redip a maximum of K times. If you use K redips, you must keep the item that you draw on your (K + 1)-th draw.

If you play optimally to maximize the value of the item you will end the game with, what is the expected value of that item?

Input

The input starts with one line containing one integer T: the number of test cases. T test cases follow.

Each test case consists of two lines. The first line consists of two integers N and K: the number of items in the bag, and the maximum number of times you may redip. The second line consists of N integers Vi, each representing the value of the i-th item.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and yis the expected value described above. Your answer will be considered correct if it is within an absolute or relative error of 10-6 of the correct answer. See the FAQ for an explanation of what that means, and what formats of real numbers we accept.

Limits

Memory limit: 1GB.
1 ≤ T ≤ 100.
1 ≤ Vi ≤ 109.
1 ≤ N ≤ 2 * 104.

Small dataset (Test set 1 - Visible)

Time limit: 20 seconds.
0 ≤ K ≤ 1.

Large dataset (Test set 2 - Hidden)

Time limit: 60 seconds.
0 ≤ K ≤ 5 * 104.

Sample


Input 
 

Output 
 
5
4 0
1 2 3 4
3 1
1 10 1
3 15
80000 80000 80000
1 1
10
5 3
16 11 7 4 1

  
Case #1: 2.500000
Case #2: 6.000000
Case #3: 80000.000000
Case #4: 10.000000
Case #5: 12.358400


  

In Sample Case #1, you cannot redip, so the expected value is just the mean of the items in the bag which is (1 + 2 + 3 + 4) / 4 = 2.5.

In Sample Case #2, the best strategy is to keep the item of value 10 if you get it, and redip otherwise. The chance of getting that item (on either the first or second draw) is 1 - (2/3)2 = 5/9, hence the expected value is (5/9 * 10) + (4/9 * 1) = 6.

In Sample Case #3, since all the items have the same value, it does not matter how many times you redip and hence the expected value is 80000.

Note that cases #3 and #5 would not appear in the Small dataset.

  • 思路:
    • 这道题小数据集给了点提示。就是k=1。能重抽一次,在哪种情况下会重抽呢 ? 就是第一次抽到的数字比期望的数字小的时候。
    • 数据的期望为e。则第一次抽取的数比e小一定会重新抽取。第二次什么时候会选择重抽?就是再抽一次的期望比不抽高。因为是第二次抽取,所以第一次只可能是抽到了比初始期望小的数。所以第二次的时候,所有比e小的数字的在计算期望的时候都可以算作e。
    • 第三次同理。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;

int main() {
    int t;
    cin >> t;
    for(int i = 0; i < t; i++) {
        int n, k, tmp;
        cin >> n >> k;
        vector<double> ns(n, 0), sns(n+1, 0);
        for(int i = 0; i < n; i++) {
            cin >> tmp;
            ns[i] = tmp;
        }
        sort(ns.begin(), ns.end());
        for(int i = 1; i <= ns.size(); i++) {
            sns[i] = sns[i - 1] + ns[i - 1];
        }
        double e = 0;
        for(int i = 0; i < k + 1; i++) {
            int x = upper_bound(ns.begin(), ns.end(), e) - ns.begin();
            e = (x * e + sns[n] - sns[x]) / (double)n;
        }
        printf("Case #%d: %.06f\n", i + 1, e);
    }
    return 0;
}

Problem3  Scrambled Words (18pts, 30pts)

Professor Scrmable noticed spelling mistakes in a research paper she was reviewing, but she had no difficulty in reading or understanding the words. Upon doing some research, she found an interesting article as described below:

According to a study at an English University, it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the correct place. The rest can be a total mess and you can still read it without a problem. This is because the human mind does not read every letter by itself but the word as a whole.

Or rather ...

Aoccdrnig to a study at an Elingsh uinervtisy, it deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the corecrt pclae. The rset can be a toatl mses and you can sitll raed it wouthit a porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe.

Professor Scrmable wants to explore this concept further and starts compiling different sentences containing similarly scrambled words to send to a popular publication. Unfortunately, the space key on the professor's keyboard is not working, so she has produced one long string of characters. She has asked you to determine how many of the words in her dictionary appear (at least once) as substrings in the long string of characters, either in their original or scrambled forms. (A scrambled form consists of the same set of letters with the first and last letters in the same places, and the others in any order.)

Note that a dictionary word can appear multiple times in the string (though it should be counted only once since we only need to know whether it shows up at least once). For example, if we had the word this in the dictionary, the possible valid words which would be counted are this (original version) and tihs (scrambled version), whereas tsihsiht and other variations are not valid since they do not start with t and end with s. Also, tistiss, and thiss are not scrambled forms, because they are not reorderings of the original set of letters.

Since the professor is extremely busy, she gives this task to you, her favorite and most trusted research assistant. Given a dictionary, can you count the number of words in the dictionary that appear as a substring in the professor's string at least once, in either their scrambled or original forms.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each testcase contains three lines. The first line contains an integer L. The second line contains a list of L words made of lowercase English letters; these make up the dictionary. The third line contains two lowercase English letters S1 and S2, and five integers NABC and DS1 and S2 are the first two characters of the professor's string SN is the length of S, and the other four integers are parameters that you should use to generate the characters of S, as follows:

First we define ord(c) as the decimal value of a character c and char(n) as the character value of a decimal n. For example, ord('a') = 97 and char(97) = 'a'. You can refer to ASCII table for other conversions. 

Now, define x1 = ord(S1), x2 = ord(S2). Then, use the recurrence below to generate xi for i = 3 to N:

  • xi = ( A * xi-1 + B * xi-2 + C ) modulo D.

We define Si = char(97 + ( xi modulo 26 )), for all i = 3 to N.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and yis the number of words from the dictionary that appear (in their original or scrambled forms, as defined above) as substrings of the given string.

Limits

1 ≤ T ≤ 20.
Memory limit: 1 GB.
No two words in the dictionary are the same.
Each word in the dictionary is between 2 and 105 letters long, inclusive.
The sum of lengths of all words in the dictionary does not exceed 105.
S1 and S2 are lowercase English letters.
0 ≤ A ≤ 109.
0 ≤ B ≤ 109.
0 ≤ C ≤ 109.
1 ≤ D ≤ 109.

Small dataset (Test set 1 - Visible)

Time limit: 20 seconds.
1 ≤ L ≤ 1000.
2 ≤ N ≤ 1000.

Large dataset (Test set 2 - Hidden)

Time limit: 150 seconds.
1 ≤ L ≤ 20000.
2 ≤ N ≤ 106.

Sample


Input 
 

Output 
 
1
5
axpaj apxaj dnrbt pjxdn abd
a a 50 1 1 1 30

  
Case #1: 4

  

In Sample Case #1, using the generation method, the generated string S is aapxjdnrbtvldptfzbbdbbzxtndrvjblnzjfpvhdhhpxjdnrbt. Scrambled or original occurences of dictionary words are highlighted as follows:

 

  • axpaj occurs in its scrambled form as aapxjdnrbtvldptfzbbdbbzxtndrvjblnzjfpvhdhhpxjdnrbt.
  • apxaj occurs in its scrambled form as aapxjdnrbtvldptfzbbdbbzxtndrvjblnzjfpvhdhhpxjdnrbt. Note that even though apxaj is the scrambled form of another dictionary word axpaj, both should be counted.
  • dnrbt occurs twice in its original form as aapxjdnrbtvldptfzbbdbbzxtndrvjblnzjfpvhdhhpxjdnrbt, though it should be counted only once.
  • pjxdn occurs in its scrambled form as aapxjdnrbtvldptfzbbdbbzxtndrvjblnzjfpvhdhhpxjdnrbt. Note this occurence overlaps with occurence of another dictionary word, but still they're counted independently.
  • abd doesn't occur at all.

Note: We do not recommend using interpreted/slower languages for the Large dataset of this problem.

  • 思路:
    • 首先按照规则把字符串拼接出来。
    • 然后将需要查找的字符串处理一下,只记录首尾字母和中间字母出现的次数。
    • 同样长度的查询字符串都是可以一起比较的。所以记录不同长度。对每种长度的字符串,以该长度为窗口,滚动查询一遍。
#include <bits/stdc++.h>

using namespace std;

struct Key {
    char first, last;
    array<int, 26> freq;
};


bool operator== (const Key &a, const Key &b) {
    return a.first == b.first && a.last == b.last && a.freq == b.freq;
}

struct KeyHash {
    size_t operator()(const Key &k) const {
        size_t res = k.first + 31*k.last;
        for (int i : k.freq) res = 31*res + i;
        return res;
    }
};

Key MakeKey(const string &word) {
    Key key{word.front(), word.back(), {}};
    for (char ch : word) key.freq[ch - 'a']++;
    return key;
}

int Solve(const vector<string> &dictionary, const string &text) {
    unordered_map<Key, int, KeyHash> groups;
    unordered_set<int> word_lengths;
    for (const string &word : dictionary) {
        word_lengths.insert(word.size());
        groups[MakeKey(word)]++;
    }
    int answer = 0;
    for (int length : word_lengths) {
        if (length > text.size()) continue;
        Key key = {};
        int i = 0;
        for (; i < length - 1; ++i) {
            key.freq[text[i] - 'a']++;
        }
        for (; i < text.size(); ++i) {
            key.first = text[i - (length - 1)];
            key.last = text[i];
            key.freq[key.last - 'a']++;
            auto it = groups.find(key);
            if (it != groups.end()) {
                answer += it->second;
                groups.erase(it);
            }
            key.freq[key.first - 'a']--;
        }
    }
    return answer;
}


int main() {
    int T = 0;
    cin >> T;
    for (int t = 1; t <= T; ++t) {
        int L = 0;
        cin >> L;
        vector<string> dictionary(L);
        for (string &word : dictionary) cin >> word;
        char S1 = 0, S2 = 0;
        int N = 0, A = 0, B = 0, C = 0, D = 0;
        cin >> S1 >> S2 >> N >> A >> B >> C >> D;
        vector<int> X(N);
        X[0] = S1;
        X[1] = S2;
        for (int i = 2; i < N; ++i) X[i] = ((long long)A*X[i - 1] + (long long)B*X[i - 2] + C)%D;
        string S;
        S.resize(N);
        S[0] = S1;
        S[1] = S2;
        for (int i = 2; i < N; ++i) S[i] = char('a' + X[i]%26);
        cout << "Case #" << t << ": " << Solve(dictionary, S) << endl;
     }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值