这题大佬在做的时候忽略了廖大神给他打重点的字典序最少,结果wa5、6次,也是悲剧,也许少几次我们就捧杯了呢。。。果然杯具了。。
题意:给n组(a,b,c)的序列,让我们队序列进行排序,排序后的结果相邻两个对的(a,b,c)满足题目所给的公式.
Problem Description
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
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
api−1+bpi−1api−1+bpi−1+cpi−1≤api+bpiapi+bpi+cpi.
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.
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
* 1≤n≤103
* 1≤ai,bi,ci≤2×109
* The sum of n does not exceed 104.
DO NOT print trailing spaces.
## Constraint
* 1≤n≤103
* 1≤ai,bi,ci≤2×109
* The sum of n does not exceed 104.
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
思路:按照正常的上述公式走可能会爆精度,稍微分子分母化一下简,变成两个乘法比较也是可以的,但是数据太大,需要用long double存,还有另外一种化简方法:(a+b)/(a+b+c) ---> 1-c/(a+b+c),这样变换之后再把除法变成乘法,就可以用unsigned long long存下来啦,然后sort排序就好。
代码:
#include <string.h>
#include <stdio.h>
#include <algorithm>
#define ull unsigned long long
using namespace std;
const int maxn = 1e3+100;
struct node{
int a,b,c,ind;
};
node gp[maxn];
int n;
bool cmp(node A,node B){
ull tx = (ull)A.c * ((ull)B.a + B.c + B.b);
ull ty = (ull)B.c * ((ull)A.a + A.c + A.b);
if(tx != ty) return tx > ty;
else return A.ind < B.ind;
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%d%d%d",&gp[i].a,&gp[i].b,&gp[i].c);
gp[i].ind = i;
}
sort(gp+1,gp+n+1,cmp);
printf("%d",gp[1].ind);
for(int i=2;i<=n;i++){
printf(" %d",gp[i].ind);
}
puts("");
}
return 0;
}