pythonで書いたらTLEしたのでhaskellで書いたけどやっぱりTLEして結局c++で書くこととなった。pypyでもだめ。

kmjpさん曰く、

このように何かしらの基準でソートする問題は、隣接する2要素についてどちらを前に持ってくるのが良いか考えると良い。

だそうな。http://kmjp.hatenablog.jp/entry/2015/12/16/0900

No.322 Geometry Dash

解法

貪欲。$O(N \log N)$。

$i$番目まで決めたとして、$i+1$番目の決定は$i$番目までの決定に影響されない。なんだか貪欲でよさそう。特に$T_i$が全て同じなら$D_i$の順で良く、$D_i$が全て同じなら$T_i$の順でよい。$\frac{D_i}{T_i}$の順が疑われるのでサンプルで試せば上手くいくので、これを投げれば通る。

実装

#include <iostream>
#include <vector>
#include <algorithm>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
using namespace std;
template <class T> istream & operator >> (istream & in, vector<T> & a) { for (T & it : a) in >> it; return in; }
template <class T> ostream & operator << (ostream & out, vector<T> const & a) { bool i = false; for (T const & it : a) { if (i) out << ' '; else i = true; out << it; } return out; }
int main() {
    int n; cin >> n;
    vector<int> t(n), d(n); cin >> t >> d;
    vector<int> xs(n); repeat (i,n) xs[i] = i;
    sort(xs.begin(), xs.end(), [&](int i, int j) { return make_pair(d[i] * t[j], - t[i]) < make_pair(d[j] * t[i], - t[j]); });
    repeat (i,n) ++ xs[i];
    cout << xs << endl;
    return 0;
}

供養

module Main where
import Control.Applicative
import Data.List
import Data.Ratio
trd3 (_, _, c) = c
main = do
    _ <- getLine
    ts <- map read . words <$> getLine
    ds <- map read . words <$> getLine
    putStrLn . unwords . map (show . trd3) . sort $ zipWith3 (\ t d i -> (d % t :: Ratio Int, - t, i)) ts ds [1 ..]

供養

#!/usr/bin/env python3
import fractions
n = int(input())
ts = list(map(int,input().split()))
ds = list(map(int,input().split()))
print(*map(lambda p: p[2], sorted(map(lambda i: (fractions.Fraction(ds[i], ts[i]), - ts[i], i+1), range(n)))))