1112 KGold

来源:互联网 发布:anitama知乎 编辑:程序博客网 时间:2024/06/11 14:38
给出N个人在0时刻的财富值M[i](所有人在0时刻的财富互不相等),以及财富增长速度S[i],随着时间的推移,某些人的财富值会超越另外一些人。如果时间足够长,对于财富增长最快的人来说,他的财富将超越所有其他对手。
求发生的前10000次超越,分别是谁超过了谁?如果总的超越次数不足10000,则输出所有超越,如果1次超越都不会发生,则输出No Solution。
输出按照超越发生的时间排序,同一时刻发生的超越,按照超越者的编号排序,如果编号也相同,则按照被超越者的编号排序。所有排序均为递增序。
Input
第1行:N,表示人的数量。(1 <= N <= 10000)第2 - N + 1行:每行2个数,分别是初始的财富值M[i],和财富增长速度S[i]。(0 <= M[i] <= 10^5, 1 <= S[i] <= 100)
Output
输出前10000次超越,超越者和被超越者的编号。如果总的超越次数不足10000,则输出所有。如果1次超越都不会发生,则输出No Solution。输出按照超越发生的时间排序,同一时刻发生的超越,按照超越者的编号排序,如果超越者编号也相同,则按照被超越者的编号排序。所有排序均为递增序。
Input示例
41 1002 1003 14 50
Output示例
2 31 32 41 4
解题思路:这道题目的要求很明确即按照超过发生的时间,输出前10000次超越。对于任意两个点如果一个点能够超过另一个点,则满足M1<M2, S1>S2,这样才会发生超越,由于S的范围为1-->100,因此我们根据S值将点分类。然后根据这个去处理,本题的难点在于在于如果利用高效的方法求解出前10000次超越,这题的优化我反正是想了好长时间的,看来以后得多做难题练思维啊,具体还是看代码吧,不太会讲。
#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>#include <algorithm>#include <functional>using namespace std;const int maxn = 10010;struct Node {    int m, id;    Node() { }    Node(int t_m, int t_id) : m(t_m), id(t_id) { }    bool operator < (const Node &p) const {        return m < p.m;    }};struct Cell {    int x, y;    int d, v;    Cell() { }    Cell(int t_x, int t_y, int t_d, int t_v) : x(t_x), y(t_y), d(t_d), v(t_v) { }    bool operator < (const Cell &c) const {        if(d * c.v == v * c.d) {            if(x == c.x) {                return y > c.y;            }            return x > c.x;        }        return d * c.v > v * c.d;    }};vector<Node> vec[101];int M[maxn], S[maxn];int pos[maxn][101];priority_queue<Cell> pq;void init() {    for(int i = 0; i < 101; ++i) {        vec[i].clear();    }    memset(pos, -1, sizeof(pos));    while(!pq.empty()) pq.pop();}int main() {    //freopen("aa.in", "r", stdin);    //freopen("bb.out", "w", stdout);    init();    int n, x, y;    Cell c1, c2;    scanf("%d", &n);    for(int i = 0; i < n; ++i) {        scanf("%d %d", &M[i], &S[i]);        vec[S[i]].push_back(Node(M[i], i));    }    for(int i = 0; i < 101; ++i) {        sort(vec[i].begin(), vec[i].end());    }    for(int i = 0; i < n; ++i) {        c1.x = c1.y = -1;        c1.d = 1000000;        c1.v = 1;        for(int j = 1; j < S[i]; ++j) {            int s = vec[j].size();            if(s == 0) continue;            for(int k = 0; k < s; ++k) {                if(vec[j][k].m > M[i]) {                    pos[i][j] = k;                    //printf("Test: %d %d %d\n", i, vec[j][k].id, pos[i][j]);                    break;                }            }            if(pos[i][j] == -1) continue;            c2.x = i;            c2.y = vec[j][pos[i][j]].id;            c2.d = vec[j][pos[i][j]].m - M[i];            c2.v = S[i] - j;            if(c1 < c2) {                x = j;                c1 = c2;            }        }        if(c1.x != -1) {            //printf("Test1: %d %d\n", c1.x, c1.y);            pos[i][x]++;            pq.push(c1);        }    }    int tot = 0;    while(!pq.empty() && tot < 10000) {        tot++;        c1 = pq.top();        pq.pop();        printf("%d %d\n", c1.x + 1, c1.y + 1);        x = c1.x;        c1.x = -1; c1.y = -1;        c1.d = 1000000, c1.v = 1;        for(int i = 1; i < S[x]; ++i) {            if(pos[x][i] != -1 && pos[x][i] < (int)vec[i].size()) {                c2.x = x;                c2.y = vec[i][pos[x][i]].id;                c2.d = vec[i][pos[x][i]].m - M[x];                c2.v = S[x] - i;                if(c1 < c2) {                    y = i;                    c1 = c2;                }            }        }        if(c1.x != -1) {            //printf("Test3: %d %d\n", c1.x, c1.y);            pos[x][y]++;            pq.push(c1);        }    }    if(tot == 0) {        printf("No Solution\n");    }    return 0;}


0 0
原创粉丝点击