2019 google kickstart round A

第一題:node

n我的,每一個人有一個對應的技能值s,如今要從n我的中選出p我的,使得他們的技能值相同。算法

顯然,若是存在p我的的技能值是相同的,輸出0就能夠了。若是不存在,就要找出p我的,對他們進行訓練,治他們的技能值相同。佈局

訓練一個小時,技能值增長1,只有一個教練,也就是隻能同時訓練一個 人。找出最佳的p我的的方案,輸出最小的訓練時間。spa

AC的代碼:blog

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;
int s[100010]; // skill score
long long int t[100010];
int e[100010];

int main()
{
    int tg;
    scanf("%d", &tg);
    int n, p;

    int ca=1;
    while(tg--) {
        scanf("%d %d", &n, &p);
        s[0] = 0;
        for(int i=1; i<=n; i++) {
            scanf("%d", &s[i]);
        }
        sort(s+1, s+n+1);

        t[0] = 0;
        for(int i=1; i<=n; i++) {
            t[i] = t[i-1] + s[i];
        }

        for(int i=p; i<=n; i++) {
            e[i] = t[i] - t[i-p];
        }

        int ans = s[p]*p - e[p];
        int cur;

        for(int i=p; i<=n; i++) {
            cur = s[i]*p - e[i];
            if(cur < ans)
                ans = cur;
        }
        printf("Case #%d: %d\n", ca, ans);
        ca++;
    }
    return 0;
}

 

第二題:it

每次給你一個R*C的矩陣,矩陣的元素不是1就是0。1表明此處是一個郵局,0表明此處一個郵局,或者理解成是一個須要郵寄的用戶。io

咱們最多能夠在某個爲0的節點上再創建一個郵局,要輸出的是每種方案中全部的用戶到最近郵局的曼哈頓距離的最大值的最小值。class

顯然,若是矩陣中都是1,都是郵局,輸出0就能夠了(家門口就是郵局)。若是矩陣中存在0,顯然「最多能夠建一次郵局」的機會必方法

需要用上,再多創建一個郵局,必定能夠減少或者不變當前郵局佈局下的曼哈頓的最大值中的最小值。
數據

那這個郵局選擇在那個0的位置呢?最直接的方法就是枚舉,枚舉每一個是0的位置,由於R和C的最大值是250。

但我寫的代碼貌似沒過較大的數據量的case。第一次參加kickstart,每臺搞明白。

代碼:

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <math.h>

using namespace std;

struct node
{
    int x, y;
    int w;
}cur;

int main()
{
    int tg;
    scanf("%d", &tg);
    int r, c;
    int man_dis;
    int ca=1;
    vector<node>que1;
    vector<node>que0;

    while(tg--) {
        que0.clear();
        que1.clear();
        scanf("%d %d", &r, &c);
        char q[300][300];
        for(int i=1; i<=r; i++) {

            scanf("%s", q[i]);
            for(int j=0; j<c; j++) {
                cur.x = i;
                cur.y = j+1;
                if(q[i][j] == '1') {
                    que1.push_back(cur);
                } else {
                    que0.push_back(cur);
                }
            }
        }

        int ans1 = 0;
        for(int i=0; i<que0.size(); i++) {

            int cur, mm=r+c+1;
            for(int j=0; j<que1.size(); j++) {
                cur = abs(que0[i].x - que1[j].x) + abs(que0[i].y - que1[j].y);
                if(cur < mm)
                    mm = cur;
            }
            que0[i].w = mm;
            if(mm > ans1)
                ans1 = mm;
        } // 找出全部普通節點的最小man距離, 找出這些距離裏面的最大距離

        if(que0.size() == 0) {
            //
            printf("Case #%d: 0\n", ca);
            ca++;
        } else {

            int ans2 = 0;
            int ans = r+c+1;

            for(int i=0; i<que0.size(); i++) {
                int x1 = que0[i].x;
                int y1 = que0[i].y;
                // 假設當前節點是郵局 更新最大的man距離
                vector<int>mandis;
                mandis.clear();
                for(int j=0; j<que0.size(); j++) {

                    int x2 = que0[j].x;
                    int y2 = que0[j].y;

                    // int dis = abs(que0[i].x - que0[j].x) + abs(que0[i].y - que0[j].y);
                    int dis = abs(x1 - x2) + abs(y1 - y2);

                    if(dis < que0[j].w) {
                        mandis.push_back(dis);
                    } else {
                        mandis.push_back(que0[j].w);
                    }
                }
                ans2 = 0;
                for(int j=0; j<mandis.size(); j++) {
                    if(i!=j && mandis[j] > ans2)
                        ans2 = mandis[j];
                }
                if(ans2 < ans)
                    ans = ans2;
            }
            printf("Case #%d: %d\n", ca, ans);
            ca++;
        }
    }
    return 0;
}

第三題:

n個座位,編號1---n,如今有q個預約,每次預約都是(L, R),如(1, 3)表示預約了一、二、3的位置。

因爲每次的座位預約可能會存在重複的座位預約而致使衝突,如今讓你經過一種算法來實現保證每一個預約的人

都能分到相同數量的k個座位,並保證這個k是最大的。沒想到好的算法,故沒有提交。(不太小數據量的狀況下

暴力應該好過。依次枚舉每一個座位,輪流分給有預約的人)。

沒有代碼!

相關文章
相關標籤/搜索