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;
}