代码改变世界

interview problems

2018-01-11 10:52  明星bigdata  阅读(153)  评论(0编辑  收藏  举报

2018.1.10.1 Eat Cheese I

房间里有多块奶酪(x,y),小老鼠一开始在(0,0),问小老鼠吃掉所有奶酪要走的最短距离。
dfs + 剪枝。

#include <iostream>
#include <vector>
#include <math.h>
#include <limits.h>

using namespace std;

double eatCheese(vector<pair<double, double>>& cheeses);
void dfs(int len, vector<pair<double, double>>& cheeses, double sum, pair<double, double>& start, double& ans, vector<bool>& visit);
int main() {
    vector<pair<double, double>> v;
    v.push_back(pair<double, double>(1.0, 1.0));
    v.push_back(pair<double, double>(2.0, 2.0));
    v.push_back(pair<double, double>(3.0, 3.0));
    cout << eatCheese(v) << endl;
    return 0;
}

double eatCheese(vector<pair<double, double>>& cheeses) {
    pair<double, double> start = {0, 0};
    vector<bool> visit(cheeses.size(), false);
    double ans = 0x7f7f7f7f;
    dfs(1, cheeses, 0.0, start, ans, visit);
    return ans;
}

void dfs(int len, vector<pair<double, double>>& cheeses, double sum, pair<double, double>& start, double& ans, vector<bool>& visit) {
    if (len > cheeses.size()) {
        ans = min(ans, sum);
        return;
    }
    if (sum > ans) return;
    for (int i = 0; i < cheeses.size(); i++) {
        if (!visit[i]) {
            visit[i] = true;
            double d = sqrt((start.first - cheeses[i].first) * (start.first - cheeses[i].first) +
                            (start.second - cheeses[i].second) * (start.second - cheeses[i].second));
            dfs(len + 1, cheeses, sum + d, cheeses[i], ans, visit);
            visit[i] = false;
        }
    }
}
View Code

 

2018.1.10.2 Eat Cheese II
房间表示为二维数组, 元素值0,1,2分别不可走,可走,奶酪。小老鼠从左上起点出发,吃掉所有奶酪,到达右下终点需要的最短路径。
dfs + bfs。

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <limits.h>

using namespace std;
int eatCheese(vector<vector<int>>& matrix);
void dfs(vector<pair<int, int>>& middle_points, vector<pair<int,int>>& points, 
    int& ans, vector<int>& path, vector<bool>& visited, vector<vector<int>>& dis);

int main() {
    int a[3] = {1, 0, 2};
    int b[3] = {1, 1, 0};
    int c[3] = {0, 2, 1};
    vector<int> v1(a, a + 3);
    std::vector<int> v2(b, b + 3);
    std::vector<int> v3(c, c + 3);
    vector<vector<int>> v;
    v.push_back(v1);
    v.push_back(v2);
    v.push_back(v3);
    cout << eatCheese(v) << endl;
    return 0;
}

int eatCheese(vector<vector<int>>& matrix) {
    int m = matrix.size(), n = matrix[0].size();
    vector<pair<int, int>> points;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (matrix[i][j] == 2) points.push_back({i, j});
        }
    }
    points.push_back({0, 0});
    points.push_back({m - 1, n - 1});
    int s = points.size();
    vector<vector<int>> dis(s, vector<int>(s, INT_MAX));
    for (int i = 0; i < s; i++) {
        for (int j = 0; j < s; j++) {
            if (i != j) dis[i][j] = bfs(matrix, i, j, s);
        }
    }
    vector<bool> visited(s - 2);
    vector<pair<int, int>> middle_points(points.begin(), points.begin() + s - 2);
    int ans = INT_MAX;
    dfs(middle_points, points, ans, path, visited, dis);
    return ans;
}


void dfs(vector<pair<int, int>>& middle_points, vector<pair<int,int>>& points, 
    int& ans, vector<int>& path, vector<bool>& visited, vector<vector<int>>& dis) {
    if (path.size() == middle_points.size()) {
        ans = min(ans, dis[middle_points.size()][path[0]] + sum + dis[path.back()][middle_points.size() + 1]);
        return;
    }
    path.push_back(start);
    for (int i = 0; i < middle_points.size(); i++) {
        if (!visited[i]) {
            visited[i] = true;
            if (path.size() > 0) sum += dis[path.back()][i];
            path.push_back(i);
            dfs(middle_points, points, ans, path, visited, dis);
            path.pop_back();
            if (path.size() > 0) sum -= dis[path.back()][i];
            visited[i] = false;
        }
    }
}


int bfs(vector<vector<int>>& matrix, int b, int e, vector<pair<int, int>>& points) {
    queue<pair<int, int>> q, next;
    set<pair<int, int>> visited;
    q.push(b);
    visited.insert(b);
    int bias[5] = {1, 0, -1, 0, 1};
    int layer = 0;
    while (!q.empty()) {
        while (!q.empty()) {
            auto cur = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) {
                int x = cur.first + bias[i], y = cur.second + bias[i + 1];
                if (x >= 0 && x < matrix.size() && y >= 0 && y < matrix[0].size() && visited.find({x, y}) == visited.end()) {
                    if (x == e.first && y == e.second) return layer + 1;
                    else next.push({x, y});
                }
            }
        }
        swap(q, next);
        layer++;
    }
    return INT_MAX;
}
View Code

 


2018.1.11.1 Round Robin
轮询调度,带权重的轮询调度
最大公约数、多个数的最大公约数、轮询调度

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

class Scheduler {
private:
    vector<int*> servers;
    int i;
public:
    Scheduler(vector<int*> v) {
        servers = v;
        i = -1;
    }
    int* choose_server() {
        int j = i;
        do {
            j = (j + 1) % servers.size();
            i = j;
            return servers[i]; 
        } while (i != j);
        return NULL;
    }
};


class WeightedScheduler{
private:
    vector<int*> servers;
    vector<int> weights;
    int i;
    int cw;
    int max_weight;
public:
    WeightedScheduler(vector<int*> s, vector<int> w) {
        servers = s;
        weights = w;
        i = -1;
        cw = 0;
        max_weight = 0;
        for (int weight : weights) max_weight = max(max_weight, weight);
    }
    // 使用cw记录当前请求应该分配给weight多大的server,
    // 将cw逐渐减小直到最后所有server在接受请求后权重都一样
    int* choose_server() {
        while(1) {
            i = (i + 1) % (servers.size());
            if (i == 0) {
                cw -= ngcd(servers.size() - 1);
                if (cw <= 0) {
                    cw = max_weight;
                    if (cw == 0) return NULL;
                }
            }
            if (weights[i] >= cw) return servers[i];
        }
    }

    int gcd(int a, int b) {
        if (a < b) swap(a, b);
        while (b) {
            a %= b;
            swap(a, b);
        }
        return a;
    }
    int ngcd(int n) {
        if (n == 0) return weights[n];
        return gcd(weights[n], ngcd(n - 1));
    }

    int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }

    int nlcm(int n) {
        if (n == 0) return weights[n];
        return lcm(weights[n], nlcm(n - 1));
    }
};


int main() {
    vector<int*> v(5, NULL);
    for (int i = 0; i < 5; i++) v[i] = new int(i);
    Scheduler s(v);
    for (int i = 0; i < 10; i++) cout << *(s.choose_server()) << " ";
    cout << endl;
    int a[5] = {2, 1, 1, 2, 1};
    vector<int> w(a, a + 5);
    WeightedScheduler w_s(v, w);
    for (int i = 0; i < 40; i++) cout << *(w_s.choose_server()) << " ";
    cout << endl;
    return 0;
}
View Code