2018湘潭邀请赛F题题解
F. Sorting
Bobo has n tuples (a1, b1, c1), (a2, b2, c2), . . . , (an, bn, cn). He would like to find the lexicographically smallest permutation p1, p2, . . . , pn of 1, 2, . . . , n such that for i ∈ {2, 3, . . . , n} it holds that
Input
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains an integer n. The i-th of the following n lines contains 3 integers ai, bi and ci.
Output
For each test case, print n integers p1, p2, . . . , pn seperated by spaces. DO NOT print trailing spaces.
Constraint
l The sum of n does not exceed 104.
l 1 ≤ n ≤ 103
l 1 ≤ ai, bi, ci ≤ 2*109
Sample Input
2
1 1 1
1 1 2
2
1 1 2
1 1 1
3
1 3 1
2 2 1
3 1 1
Sample Output
2 1
1 2
1 2 3
相信大部分读完题的人第一反应是用sort的cmp函数比较,此题有个精度的坑。不过,比赛时队友运气好变量用double就过了,想向欧皇下跪,比赛结束感觉还是不对劲,遂按比赛思路再写一遍,果不其然wrong answer。
保证高精度也蛮简单,只要用无符号长整型存数据,然后把不等式交叉相乘再消下元即可。Too simple
附上AC代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int SIZE = 1e3+50; struct node { unsigned long long a, b, c; int mark; }; bool cmp(const node x, const node y) { auto m = (x.a+x.b)*(y.c); auto n = (x.c)*(y.a+y.b); if(m == n) return x.mark < y.mark; else return m < n; } int main() { int n; while(scanf("%d", &n) != EOF) { node gru[SIZE]; for(int i = 0; i < n; i++) { gru[i].mark = i+1; scanf("%llu %llu %llu", &gru[i].a, &gru[i].b, &gru[i].c); } sort(gru, gru+n, cmp); printf("%d", gru[0].mark); for(int i = 1; i < n; i++) { printf(" %d", gru[i].mark); } printf("\n"); } return 0; }