zoukankan      html  css  js  c++  java
  • topcoder srm 515 div1

    problem1 link

    暴力枚举即可。

    problem2 link

    一共有24小时,所以最多有24个顾客。设$f[x][y][z]$表示还剩下$x$把刀,现在时间是$y$,以及来过的顾客集合为$z$可以获得的最大值。

    那假设第$y$小时来的顾客为$t$,来的概率为$p$,有三种情况:

    (1)之前它来过,那么$f[x][y][z]=f[x][y+1][z]$

    (2)之前没来过,现在也没来,$f[x][y][z]=(1-p)*f[x][y+1][z]$

    (3)之前没来过,现在来了。可以选择买给他一把刀,$c_{1}=f[x-1][y+1][z|2^{t}]+v_{y}$;或者不卖给他,$c_{2}=f[x][y+1][z|2^{t}]$,所以$f[x][y][z]=max(c_{1},c_{2})*p$

    另外,假设一个人第一次,第二次来的概率分别为0.2和0.4。那么上面使用的$p$是假设他之前没来过。如果第一次没来,那么第二次来的概率为$frac{0.4}{1-0.2}$

    problem3 link

    首先枚举字母'R'和‘F’的位置$p_{1},p_{2}$。然后计算和其他所有‘L’的答案。

    首先,对于每个位置$(x,y)$,计算其函数值$g(x,y)=distance(p_{1},p_{x,y})+distance(p_{2},p_{x,y})$

    然后新建一系列节点$S_{0},S_{1},S_{2},...$。

    对于每个$(x,y)$,设$t=g(x,y)$。那么节点$S_{t-1}$向点$(x,y)$连有向边。

    另外节点$S_{i}$到$S_{i+1}$有一条有向边。每个点$(x,y)$向四周的格子有四条有向边。

    所有边的长度均为1.然后从节点$S_{0}$开始进行bfs,计算到达每个点的距离。每个‘L’字母计算的距离就是选择$p_{1},p_{2}$和该位置的答案。 

    code for problem1

    class RotatedClock {
       public:
        string getEarliest(int hourHand, int minuteHand) {
            for (int i = 0; i < 12; ++i) {
                for (int j = 0; j < 60; j += 2) {
                    for (int k = 0; k < 12; ++k) {
                        if (Check(i, j, k, hourHand, minuteHand)) {
                            return ToString(i) + ":" + ToString(j);
                        }
                    }
                }
            }
            return "";
        }
    
        string ToString(int x) {
            stringstream ss;
            if (x < 10) {
                ss << "0" << x;
            } else {
                ss << x;
            }
            return ss.str();
        }
    
        bool Check(int h, int m, int b, int hHand, int mHand) {
            return GetHourHand(h, m, b) == hHand && GetMinuteHand(m, b) == mHand;
        }
    
        int GetHourHand(int h, int m, int b) {
            int result = 0;
            if (h >= b) {
                result = (h - b) * 30 + m / 2;
            } else {
                result = 360 - (b - h) * 30 + m / 2;
            }
            return result;
        }
        int GetMinuteHand(int m, int b) {
            b *= 5;
            if (m >= b) {
                return (m - b) * 6;
            }
            else {
                return 360 - (b - m) * 6;
            }
        }
    
    };
    

    code for problem2

    double cache[25][24][1 << 12];
    int visited[25][24][1 << 12];
    
    class NewItemShop {
       public:
        double getMaximum(int swords, vector<string> customers) { 
            Init(customers);
            memset(visited, 0, sizeof(visited));
            return dfs(swords, 0, 0);
        }
    
        double dfs(int swords, int hour, int mask) {
            if (swords == 0 || hour == 24) {
                return 0;
            }
            if (visited[swords][hour][mask] != 0) {
                return cache[swords][hour][mask];
            }
            visited[swords][hour][mask] = 1;
            if (!hour_[hour].inited_) {
                return cache[swords][hour][mask] = dfs(swords, hour + 1, mask);
            }
    
    
            int cMask = hour_[hour].mask();
            double p = hour_[hour].probility_;
            int val = hour_[hour].value_;
    
            if ((mask & cMask) > 0) {
                return cache[swords][hour][mask] = dfs(swords, hour + 1, mask);
            }
    
            cache[swords][hour][mask] = (1 - p) * dfs(swords, hour + 1, mask);
    
            double c0 = dfs(swords, hour + 1, mask | cMask);
            double c1 = dfs(swords - 1, hour + 1, mask | cMask) + val;
    
            cache[swords][hour][mask] += max(c0, c1) * p;
    
            return cache[swords][hour][mask];
        }
    
       private:
    
    
        struct HourInfo {
            bool is_multiple_times_;
            int multiple_index_;
            double probility_;
            int value_;
    
            bool inited_;
    
            HourInfo():inited_(false) {}
    
            int mask() const {
                if (!is_multiple_times_) {
                    return 0;
                }
                return 1 << multiple_index_;
            }
    
    
        }hour_[24];
    
        void Init(const vector<string>& customers) {
            for (int i = 0; i < 24; ++ i) {
                hour_[i].inited_ = false;
            }
            int multiple_num = 0;
            for (int i = 0; i < (int)customers.size(); ++ i) {
                const vector<int> a = Split(customers[i]);
                const int n = (int)a.size();
                const int idx = n > 3 ? multiple_num ++ : 0;
                double cur = 1.0;
                for (int j = 0; j < n; j += 3) {
                    int h = a[j];
                    int v = a[j + 1];
                    double p = a[j + 2] / 100.0 / cur;
                    cur -= a[j + 2] / 100.0;
                    if (n > 3) {
                        hour_[h].is_multiple_times_ = true;
                        hour_[h].multiple_index_ = idx;
                    }
                    else {
                        hour_[h].is_multiple_times_ = false;
                    }
                    hour_[h].probility_ = p;
                    hour_[h].value_ = v;
                    hour_[h].inited_ = true;
                }
            }
        }
    
        std::vector<int> Split(const std::string& s) {
            std::vector<int> result;
            const int len = (int)s.length();
            int idx = 0;
            while (idx < len) {
                while (idx < len && !IsDigit(s[idx])) {
                    ++ idx;
                }
                if (idx >= len) {
                    break;
                }
                int x = 0;
                while (idx < len && IsDigit(s[idx])) {
                    x = x * 10 + s[idx++] - '0';
                }
                result.push_back(x);
            }
            return result;
        }
    
        static bool IsDigit(char c) {
            return '0' <= c && c <= '9';
        }
    };
    

      


    code for problem3

    class MeetInTheMaze {
       public:
        string getExpected(vector<string> maze) {
            Initialize(maze);
            std::vector<std::pair<int, int>> all_f_positions;
            std::vector<std::pair<int, int>> all_r_positions;
            int l_number = 0;
            for (int i = 0; i < height_; ++i) {
                for (int j = 0; j < width_; ++j) {
                    char ch = maze_[i][j];
                    if (ch == 'F') {
                        all_f_positions.push_back(std::make_pair(i, j));
                    } else if (ch == 'R') {
                        all_r_positions.push_back(std::make_pair(i, j));
                    } else if (ch == 'L') {
                        ++l_number;
                    }
                }
            }
            int total = 0;
            for (auto f : all_f_positions) {
                for (auto r : all_r_positions) {
                    int t = Calculate(f.first, f.second, r.first, r.second);
                    if (t == -1) {
                        return "";
                    }
                    total += t;
                }
            }
            int d = (int)all_f_positions.size() * (int)all_r_positions.size() *
                    l_number;
            int g = Gcd(total, d);
            total /= g;
            d /= g;
            std::stringstream ss;
            ss << total << "/" << d;
            return ss.str();
        }
    
        ~MeetInTheMaze() { delete[] distance_; }
    
       private:
        int Calculate(const int f_x, const int f_y, const int r_x, const int r_y) {
            std::vector<std::vector<std::pair<int, int>>> new_graph(
                (width_ + height_) << 1);
            for (int i = 0; i < height_; ++i) {
                for (int j = 0; j < width_; ++j) {
                    if (maze_[i][j] != '#') {
                        int d1 = GetDistance(f_x, f_y, i, j);
                        int d2 = GetDistance(r_x, r_y, i, j);
                        if (d1 == -1 || d2 == -1) {
                            continue;
                        }
                        int d = d1 + d2;
                        if (d > (int)new_graph.size()) {
                            new_graph.resize(d);
                        }
                        new_graph[d - 1].push_back(std::make_pair(i, j));
                    }
                }
            }
            const int nodes = (int)new_graph.size();
            std::vector<int> dist(height_ * width_ + nodes, -1);
    
            dist[height_ * width_] = 0;
            std::queue<int> a_queue;
            a_queue.push(height_ * width_);
            const int dx[] = {1, -1, 0, 0};
            const int dy[] = {0, 0, 1, -1};
            while (!a_queue.empty()) {
                const int start = a_queue.front();
                a_queue.pop();
                if (start < width_ * height_) {
                    const int sx = start / width_;
                    const int sy = start % width_;
                    for (int i = 0; i < 4; ++i) {
                        int x = sx + dx[i];
                        int y = sy + dy[i];
                        if (0 <= x && x < height_ && 0 <= y && y < width_) {
                            if (maze_[x][y] == '#') {
                                continue;
                            }
                            if (dist[x * width_ + y] == -1) {
                                dist[x * width_ + y] = dist[start] + 1;
                                a_queue.push(x * width_ + y);
                            }
                        }
                    }
                } else {
                    const int new_graph_index = start - width_ * height_;
                    for (auto son : new_graph[new_graph_index]) {
                        int x = son.first;
                        int y = son.second;
                        int key = x * width_ + y;
                        if (dist[key] == -1) {
                            dist[key] = dist[start] + 1;
                            a_queue.push(key);
                        }
                    }
                    if (new_graph_index + 1 < nodes) {
                        dist[start + 1] = dist[start] + 1;
                        a_queue.push(start + 1);
                    }
                }
            }
            int total = 0;
            for (int i = 0; i < height_; ++i) {
                for (int j = 0; j < width_; ++j) {
                    if (maze_[i][j] == 'L') {
                        if (dist[i * width_ + j] == -1) {
                            return -1;
                        }
                        total += dist[i * width_ + j];
                    }
                }
            }
            return total;
        }
    
        int Gcd(int x, int y) { return y == 0 ? x : Gcd(y, x % y); }
    
        void Initialize(const std::vector<std::string> &maze) {
            maze_ = maze;
            height_ = (int)maze_.size();
            width_ = (int)maze_[0].size();
            const int total_size = width_ * width_ * height_ * height_;
            distance_ = new int[total_size];
            memset(distance_, -1, sizeof(int) * total_size);
        }
    
        int GetDistance(int start_x, int start_y, int end_x, int end_y) {
    
            if (start_x > end_x || (start_x == end_x && start_y > end_y)) {
                std::swap(start_x, end_x);
                std::swap(start_y, end_y);
            }
    
            int key = GetKey(start_x, start_y, end_x, end_y);
            if (distance_[key] == -1) {
                CalculateDistanceFrom(start_x, start_y);
            }
            return distance_[key];
        }
    
        void CalculateDistanceFrom(const int start_x, const int start_y) {
            std::queue<std::pair<int, int>> a_queue;
            a_queue.push(std::make_pair(start_x, start_y));
            distance_[GetKey(start_x, start_y, start_x, start_y)] = 0;
            const int dx[] = {1, -1, 0, 0};
            const int dy[] = {0, 0, 1, -1};
            while (!a_queue.empty()) {
                const int sx = a_queue.front().first;
                const int sy = a_queue.front().second;
                a_queue.pop();
                const int from_key = GetKey(start_x, start_y, sx, sy);
                for (int i = 0; i < 4; ++i) {
                    int x = sx + dx[i];
                    int y = sy + dy[i];
                    if (0 <= x && x < height_ && 0 <= y && y < width_) {
                        if (maze_[x][y] == '#') {
                            continue;
                        }
                        int key = GetKey(start_x, start_y, x, y);
                        if (distance_[key] != -1) {
                            continue;
                        }
                        distance_[key] = distance_[from_key] + 1;
                        a_queue.push(std::make_pair(x, y));
                    }
                }
            }
        }
    
        int GetKey(int x1, int y1, int x2, int y2) const {
            return x1 * width_ * height_ * width_ + y1 * height_ * width_ +
                   x2 * width_ + y2;
        }
    
        int width_;
        int height_;
        std::vector<std::string> maze_;
        int *distance_;  
    };
    

      

  • 相关阅读:
    处理sevenzipsharp 检查密码函数的Bug
    C# 开源压缩组件比较
    css 一些技巧
    input 限制输入
    原生JS实现淡入淡出效果(fadeIn/fadeOut/fadeTo)
    js string.format 方法
    Atom插件及使用
    chrome浏览器的跨域设置-包括版本49前后两种设置 ,windows&mac
    原生js监听input值改变事件
    html5 tab横向滚动,无滚动条(transform:translate)
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/8278940.html
Copyright © 2011-2022 走看看