阿里2017算法工程师在线笔试编程——8月25日

来源:互联网 发布:知乎专栏文章排版 编辑:程序博客网 时间:2024/05/17 02:24

题1:周期开放点的最短路问题

题目描述:给定拓扑结构,两点间距离,源点,汇点,每个节点周期性开放关闭,各点周期不同。

求:源点到汇点的最短时间。

例子:

90 31 52 73 34 55 76 97 38 5140 1 40 7 81 2 81 7 112 3 72 5 42 8 23 4 93 5 144 5 105 6 26 8 66 7 17 8 704

点数
点数 周期

边数
边起点 边汇点 距离

源点
汇点

解释:9个点,1编号点,周期5,0时刻开启,5时刻关闭,10时刻开启,依次类推。如到达ID_1点在时刻5,则需要等待到时刻10。到达于时刻4,则立即出发。

最短路问题,可用动态规划,因为到达其中任何一个点的最短路径(包括在该点等待时间)可用Dijkstra里的思想求。

代码:

#include <iostream>#include <vector>#include <list>#include <queue>#include <functional>#include <numeric>#include <limits>using namespace std;/** 请完成下面这个函数,实现题目要求的功能 **//** 当然,你也可以不按照这个模板来作答,完全按照自己的想法来 ^-^  **/int minTravelTime(int N, vector < vector < int > > intersections, int M, vector < vector < int > > roads, int s, int t) {    int ans = 0;    //read T    vector<int> T(N);    for (auto &it1 : intersections) {        T[it1[0]] = it1[1];    }    //read adjlist    using edge = pair<int, int>;    vector<list<edge>> adjlist(N);    for (auto &rd : roads) {        adjlist[rd[0]].emplace_back(make_pair(rd[1], rd[2]));    }    //make priority_queue    using distid = pair<int, int>;    priority_queue<distid, vector<distid>, greater<distid> > q;    //make dist vector    vector<int> dist(N,INT_MAX),done(N,0);    dist[s] = 0;    q.push(make_pair(dist[s], s));    while (!q.empty()) {        auto u = q.top();        q.pop();        int id = u.second;        if (done[id])continue;        done[id] = 1;        for (const auto &p : adjlist[id]) {            int tt = T[p.first];//周期            int tmp = u.first + p.second;//到达u.first点的时间            if ((tmp / tt) & 1)tmp = (tmp / tt + 1)*tt;//考虑周期            if (tmp < dist[p.first]) {                if (p.first == t)ans = u.first+p.second;                dist[p.first] = tmp;                q.push(make_pair(dist[p.first], p.first));            }        }    }    return ans;//到达的时间     //注:这里记不清求的是可以离开t的最短时间还是到达t的最短时间    return dist[t];//可以离开的时间}int main() {//读取函数是编程平台给的// #ifdef _WIN32 for debug//  freopen("in.txt", "r", stdin);// #endif // _WIN32    int res;    int _N;    cin >> _N;    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');    int _intersections_rows = _N;    int _intersections_cols = 2;    vector< vector < int > > _intersections(_intersections_rows);    for (int _intersections_i = 0; _intersections_i < _intersections_rows; _intersections_i++) {        for (int _intersections_j = 0; _intersections_j < _intersections_cols; _intersections_j++) {            int _intersections_tmp;            cin >> _intersections_tmp;            _intersections[_intersections_i].push_back(_intersections_tmp);        }    }    int _M;    cin >> _M;    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');    int _roads_rows = _M;    int _roads_cols = 3;    vector< vector < int > > _roads(_roads_rows);    for (int _roads_i = 0; _roads_i < _roads_rows; _roads_i++) {        for (int _roads_j = 0; _roads_j < _roads_cols; _roads_j++) {            int _roads_tmp;            cin >> _roads_tmp;            _roads[_roads_i].push_back(_roads_tmp);        }    }    int _s;    cin >> _s;    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');    int _t;    cin >> _t;    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');    res = minTravelTime(_N, _intersections, _M, _roads, _s, _t);    cout << res << endl;// #ifdef _WIN32//  fclose(stdin);// #endif // _WIN32    return 0;}

题2:菜鸟仓库货架编号问题

题目描述:一个数字代表一个货架。如下编码:1|12|123|1234|12345|……|12345678910111213141516|

求:第K个货物的代表数字是几。例如第三个货物是2,第10个货物是4。

/** 请完成下面这个函数,实现题目要求的功能 **//** 当然,你也可以不按照这个模板来作答,完全按照自己的想法来 ^-^  **/#include <stdio.h>  #include <math.h>  #include <stdlib.h>#define getN(x) ((int)log10(x)+1)using ull = unsigned long long;ull summ[5000];//5000足够K最大值void pre_calc() {    ull tmp[5000] = { 0 };    tmp[1] = summ[1] = 1;    for (int i = 2; i < 5000; i++)    {        tmp[i] = tmp[i - 1] + getN(i);//每个格子的长度        summ[i] = summ[i - 1] + tmp[i];//累计长度    }}int Get(int n) {    int i = 1, position, len;    while (summ[i] < n)i++;//找到格子    position = n - summ[i - 1];//在格子中的偏移    len = 0;    for (i = 1; len < position; i++) {        len += getN(i);    }    //找到那个货架所在的数i-1,及在这个数中的位数,len-position,=0:个位,=1:十位    // do something    int x = (i - 1) / (int)pow(10, len - position) % 10;    return x;}int main(){    pre_calc();    int n;    scanf("%d", &n);    int r = Get(n);    printf("%d\n", r);}
阅读全文
0 0
原创粉丝点击