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
- 1112 KGold
- 51Nod-1112-KGold
- 51Nod-1112-KGold(直线相交)
- 51NOD1112 KGold
- 1112
- 1112
- 1112
- 1112
- 1112
- 1112
- 1112
- 1112
- 1112
- poj 1112
- 1112 水题
- poj 1112
- LightOj 1112
- primer 1112
- 部署在Openshift云主机的Java开源论坛
- C#网络编程(异步传输字符串)
- boost 已解决
- 从Viola&Jones的人脸检测说起
- C#网络编程(同步传输字符串)
- 1112 KGold
- ant全自动更新部署web程序的详解
- 字符串
- 七大排序实测(计数、快速、归并、大堆、希尔、插入、选择)
- Linux(centos 6.5) 调用java脚本以及定时执行的脚本实例及配置文件详解
- pandas+numpy ufunc重写question2计算位温
- 使用Spring容器
- YII1.0中验证码刷新不更新的问题的解决。
- C#中的委托和事件