【Kickstart】2018 Round (Practice ~ C)

Practice Round

Problem A GBus count (9pt/15pt) (2019年1月14日,kickstart羣每日一題)

題意:有一條筆直的大路,上面有城市編號從 1 開始從左到右一次排列。上面有 N 個 GBuses, 每個 bus[i] 鏈接 A[i]  到 B[i] 兩個地點(包含這兩個地方)。咱們想要求 P 個城市,每一個城市通過的公交車數量。node

輸入輸出 和 數據規模 以下:ios

There exist some cities that are built along a straight road. The cities are numbered 1, 2, 3... from left to right.
There are N GBuses that operate along this road. For each GBus, we know the range of cities that it serves: the i-th gBus serves the cities with numbers between Ai and Bi, inclusive.
We are interested in a particular subset of P cities. For each of those cities, we need to find out how many GBuses serve that particular city.
Input
The first line of the input gives the number of test cases, T. Then, T test cases follow; each case is separated from the next by one blank line. (Notice that this is unusual for Kickstart data sets.)
In each test case: The first line contains one integer N: the number of GBuses. The second line contains 2N integers representing the ranges of cities that the buses serve, in the form A1 B1 A2 B2 A3 B3 ... AN BN. That is, the first GBus serves the cities numbered from A1 to B1 (inclusive), and so on. The third line contains one integer P: the number of cities we are interested in, as described above. (Note that this is not necessarily the same as the total number of cities in the problem, which is not given.) Finally, there are P more lines; the i-th of these contains the number Ci of a city we are interested in.
Output For each test case, output one line containing Case #x: y, where x is the number of the test case (starting from 1), and y is a list of P integers, in which the i-th integer is the number of GBuses that serve city Ci. Limits 1 ≤ T ≤ 10. Small dataset 1 ≤ N ≤ 50 1 ≤ Ai ≤ 500, for all i. 1 ≤ Bi ≤ 500, for all i. 1 ≤ Ci ≤ 500, for all i. 1 ≤ P ≤ 50. Large dataset 1 ≤ N ≤ 500. 1 ≤ Ai ≤ 5000, for all i. 1 ≤ Bi ≤ 5000, for all i. 1 ≤ Ci ≤ 5000, for all i. 1 ≤ P ≤ 500.

題解:咱們只須要把每一個bus的起點和終點讀進來,而後對於每個城市,都去每一個bus的區間裏面查這個城市是否是在這個bus區間裏面,是的話就加一。git

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 
 8 using namespace std;
 9 
10 void print(vector<pair<int, int>>& bus) {
11   for (int i = 0; i < bus.size(); ++i) {
12     printf("%d -> %d \n", bus[i].first, bus[i].second);
13   }
14 }
15 void solve(const int id) {
16   int n, p;
17   cin >> n;
18   vector<pair<int, int>> bus(n);
19   for (int i = 0; i < n; ++i) {
20     int s, e;
21     cin >> s >> e;
22     if (s > e) { 
23       swap(s, e); 
24     }
25     bus[i] = make_pair(s, e);
26   }
27 // print(bus);
28   cin >> p;
29   vector<int> ans(p, 0);
30   for (int i = 0; i < p; ++i) {
31     int city;
32     cin >> city;
33     for (auto b : bus) {
34       if (city >= b.first && city <= b.second) {
35         ans[i]++;
36       }
37     }
38   }
39   printf("Case #%d:", id);
40   for (auto e : ans) {
41     printf(" %d", e);
42   }
43   printf("\n");
44   return;
45 }
46 int main () {
47   int t;
48   cin >> t;
49   for (int idx = 1; idx <= t; ++idx) {
50     solve(idx);
51   }
52   return 0;
53 }
View Code

 總監說線段樹,我下週學習一下線段樹==算法

 

Problem B Googol String (7pt/12pt) (2019年1月15日, kickstart羣每日一題)

給了一個很是長的字符串,有必定的生成規則,問字符串的第 K 個字母是啥。數組

A "0/1 string" is a string in which every character is either 0 or 1. There are two operations that can be performed on a 0/1 string:ide

  • switch: Every 0 becomes 1 and every 1 becomes 0. For example, "100" becomes "011".
  • reverse: The string is reversed. For example, "100" becomes "001".

Consider this infinite sequence of 0/1 strings:
S0 = ""
S1 = "0"
S2 = "001"
S3 = "0010011"
S4 = "001001100011011"
...
SN = SN-1 + "0" + switch(reverse(SN-1)).
You need to figure out the Kth character of Sgoogol, where googol = 10^100.
Input
The first line of the input gives the number of test cases, T. Each of the next T lines contains a number K.
Output
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the Kth character of Sgoogol.
Limits
1 ≤ T ≤ 100.
Small dataset
1 ≤ K ≤ 10^5.
Large dataset
1 ≤ K ≤ 10^18.學習

 

題解:小數據暴力能夠解出來,大數據不行。大數據看了下答案學習了一下。整個字符串呈中心對稱(字符串數組 1-based),2^k 的位置確定是 0, 左右子串中心對稱,而且須要 switch 0,1. 代碼怎麼寫須要複習,一開始還沒搞明白怎麼寫。明天覆習。大數據

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 
 8 using namespace std;
 9 typedef long long ll;
10 
11 int bst(ll k, int x);
12 int solve() {
13   ll k;
14   scanf("%lld", &k);
15   return bst(k, 60); //2^60 > 1e18
16 }
17 // string is 1-based.
18 int bst(ll k, int x) {
19   ll sz = 1LL << x;
20   if (k == sz) { return 0; }
21   if (k < sz) {  //left substr
22     return bst(k, x-1);
23   }
24   if (k > sz) { // right substr
25     return 1 ^ bst(sz - (k - sz), x-1); //return 1 - bst(sz - (k - sz), x-1);
26   }
27   return -1;
28 }
29 int main () {
30   int t;
31   cin >> t;
32   for (int idx = 1; idx <= t; ++idx) {
33     int ret = solve();
34     printf("Case #%d: %d\n", idx, ret);
35   }
36   return 0;
37 }
View Code

 

Problem C Sort a scarmbled itinerary (11pt/15pt)

Problem D Sums of Sums (8pt/28pt)

 

Round A

Problem A Even Digits (8pt/15pt)

 

Problem B Lucky Dip (10pt/19pt) (2019年1月23日,kickstart羣每日一題)

https://code.google.com/codejam/contest/9234486/dashboard#s=p1&a=1優化

袋子裏面有 N 個物品,每一個物品都有它的價值,每次從袋子裏面取一個物品出來,有 K 次往回丟的機會。咱們的目標是最大化物品價值的指望值。求最大指望。ui

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 y is 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

1 ≤ T ≤ 100.
1 ≤ Vi ≤ 109.
1 ≤ N ≤ 20000.

Small dataset

0 ≤ K ≤ 1.

Large dataset

0 ≤ K ≤ 50000.

Input                         
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
Output
Case #1: 2.500000
Case #2: 6.000000
Case #3: 80000.000000
Case #4: 10.000000
Case #5: 12.358400

題解:若是 k == 0, 那麼指望值就是全部物品價值的平均值。若是 k > 0, 咱們能夠想像一下,對於第 i 次咱們取出來的物品,若是當前物品的價值大於 i - 1 次的指望值,那麼就就留下,若是小於第 i - 1次的指望值,那麼就扔回去。

因此,指望的計算公式是 E[0] = sigma(vi), E[i] = sigma(Max(vi, E[i-1]))/N, 返回 E[k]. 暴力算法的時間複雜度是 O(NK)

本題能夠用二分優化,先對物品價值進行排序,每次二分出來比E[i-1]大的區間,而後累加。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 #include <unordered_set>
 8 #include <unordered_map>
 9 
10 using namespace std;
11 
12 void solve(int id) {
13     double res = 0.0;
14     int n, k;
15     cin >> n >> k;
16     int number; long long total = 0;
17     unordered_map<int, int> freq;
18     for (int i = 0; i < n; ++i) {
19       cin >> number;
20       total += (long long)number;
21       freq[number]++;
22     }
23     vector<double> e(k+1, 0.0);
24     e[0] = (double)total / n;
25     double t = 0;
26     for (int i = 1; i <= k; ++i) {
27         double t = 0.0;
28         for (auto p : freq) {
29           t += max((double)p.first, (double)e[i-1]) * (double)p.second;
30         }
31         e[i] = t / (double)n;
32     }
33     res = e[k];
34     printf("Case #%d: %lf\n", id, res);
35 }
36 int main () {
37   int t;
38   cin >> t;
39   for (int idx = 1; idx <= t; ++idx) {
40     solve(idx);
41   }
42   return 0;
43 }
brute force

 

Problem C Scrambled Words (18pt/30pt)

 

Round B

Problem A No Line (7pt/13pt)

Problem B Sherlock and Bit Strings (11pt/26pt)

Problem C King's Circle (16pt/27pt)

 

Round C

連接:https://code.google.com/codejam/contest/4384486/dashboard

Problem A Planet Distance (10pt/15pt) (2019年1月29日,打卡羣)

題意是說,給了一個無向圖, 裏面有個環,要求返回一個距離數組,環上的點在距離數組上都是 0, 不在環上的點,在距離數組上都是距離環的距離。

題解:如何找到一個無向圖的環。用kahn算法的思想,bfs解法。先讀入邊,而後用鄰接鏈表來存儲,而後計算每一個節點的度(無向圖,度就是結點上的邊數)。找到全部度爲 1 的結點,把這些結點放進隊列。而後把結點pop出隊列的時候,至關於在圖上把這個結點給刪除了。因此,和這個結點相鄰的結點的度也應該減一。遍歷全部跟當前結點相鄰的結點。若是相鄰結點的邊數還剩下一條而且它沒有被訪問過的話,就把這個相鄰的結點也放進隊列(變成要刪除的的結點,至關於放進一個刪除的緩衝區)。bfs的完畢以後,咱們找到全部度不爲0的結點,那麼就是環上的結點了。

如何求剩下的結點距離環的距離。把全部環上的結點放進隊列。而後遍歷相鄰結點計算距離(仍是bfs,這個我會==)

時間複雜度是 O(N) 的。此外還有一個實現上的小問題,就是若是變量搞成全局變量的話,每次讀新的test case,要注意清空啊==

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <string>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <queue>
 9 #include <unordered_set>
10 #include <unordered_map>
11 
12 using namespace std;
13 
14 int v;
15 unordered_map<int, vector<int>> edges;
16 vector<int> degree;
17 void getInput() {
18   edges.clear();
19   degree.clear();
20   cin >> v;
21   degree = vector<int>(v + 1, 0);
22   for (int i = 0; i < v; ++i) {
23     int s, e;
24     cin >> s >> e;
25     edges[s].push_back(e);
26     degree[s]++;
27     edges[e].push_back(s);
28     degree[e]++;
29   }
30 }
31 
32 vector<int> planetDistance() {
33   queue<int> que;
34   vector<int> visited(v+1, 0);
35   for (int i = 1; i <= v; ++i) {
36     if (degree[i] == 1) {
37       que.push(i);
38       degree[i]--;
39       visited[i] = 1; //i has been visited
40     }
41   }
42   while (!que.empty()) {
43     int curNode = que.front(); que.pop();
44     for (auto adjNode : edges[curNode]) {
45       if (visited[adjNode] == 0 && --degree[adjNode] == 1) {
46         que.push(adjNode);
47         degree[adjNode]--;
48         visited[adjNode] = 1;
49       }
50     }
51   }
52   vector<int> ret(v+1, v+1);
53   que = queue<int>(); //clear queue
54   for (int i = 1; i <= v; ++i) {
55     if (degree[i] != 0) {
56       que.push(i);
57       ret[i] = 0; //node i is in the circle.
58     }
59   }
60   while (!que.empty()) {
61     int curNode = que.front(); que.pop();
62     for (auto adjNode : edges[curNode]) {
63       if (visited[adjNode] == 1) {
64         ret[adjNode] = ret[curNode] + 1;
65         visited[adjNode] = 0;
66         que.push(adjNode);
67       }
68     }
69   }
70   vector<int> res(ret.begin() + 1, ret.end());
71   return res;
72 }
73 
74 void solve(const int id) {
75   getInput();
76   vector<int> res = planetDistance();
77   printf("Case #%d:", id);
78   for (auto r : res) {
79     cout << " " << r ;
80   }
81   cout << endl;
82 }
83 int main () {
84 int t;
85 cin >> t;
86   for (int idx = 1; idx <= t; ++idx) {
87     solve(idx);
88   }
89   return 0;
90 }
View Code

 

Problem B Fairies and Witches (15pt/21pt)

Problem C Kickstart Alarm (13pt/26pt)

相關文章
相關標籤/搜索