1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | import Data.List import Data.Array import Data.Maybe data Point a = P a a deriving ( Show , Ord , Eq ) data Vector a = V a a deriving ( Show , Ord , Eq ) data Turn = S | L | R deriving ( Show , Eq , Ord , Enum ) --start of convex hull compPoint :: ( Num a , Ord a ) => Point a -> Point a -> Ordering compPoint ( P x1 y1 ) ( P x2 y2 ) | compare x1 x2 == EQ = compare y1 y2 | otherwise = compare x1 x2 sortPoint :: ( Num a , Ord a ) => [ Point a ] -> [ Point a ] sortPoint xs = sortBy ( \ x y -> compPoint x y ) xs findTurn :: ( Num a , Ord a , Eq a ) => Point a -> Point a -> Point a -> Turn findTurn ( P x0 y0 ) ( P x1 y1 ) ( P x2 y2 ) | ( y1 - y0 ) * ( x2- x0 ) < ( y2 - y0 ) * ( x1 - x0 ) = L | ( y1 - y0 ) * ( x2- x0 ) == ( y2 - y0 ) * ( x1 - x0 ) = S | otherwise = R hullComputation :: ( Num a , Ord a ) => [ Point a ] -> [ Point a ] -> [ Point a ] hullComputation [x] ( z:ys ) = hullComputation [z,x] ys hullComputation xs [] = xs hullComputation ( y : x : xs ) ( z : ys ) | findTurn x y z == R = hullComputation ( x:xs ) ( z : ys ) | findTurn x y z == S = hullComputation ( x:xs ) ( z : ys ) | otherwise = hullComputation ( z : y : x : xs ) ys convexHull :: ( Num a , Ord a ) => [ Point a ] -> [ Point a ] convexHull [] = [] convexHull [ p ] = [ p ] convexHull [ p1 , p2 ] = [ p1 , p2 ] convexHull xs = final where txs = sortPoint xs ( x : y : ys ) = txs lhull = hullComputation [y,x] ys ( x': y' : xs' ) = reverse txs uhull = hullComputation [ y' , x' ] xs' final = ( init lhull ) ++ ( init uhull ) --end of convex hull --dot product for getting angle angVectors :: ( Num a , Ord a , Floating a ) => Vector a -> Vector a -> a angVectors ( V ax ay ) ( V bx by ) = theta where dot = ax * bx + ay * by a = sqrt $ ax ^ 2 + ay ^ 2 b = sqrt $ bx ^ 2 + by ^ 2 theta = acos $ dot / a / b --start of rotating caliper part http://en.wikipedia.org/wiki/Rotating_calipers --rotate the vector x y by angle t rotVector :: ( Num a , Ord a , Floating a ) => Vector a -> a -> Vector a rotVector ( V x y ) t = V ( x * cos t - y * sin t ) ( x * sin t + y * cos t ) --square of dist between two points distPoints :: ( Num a , Ord a , Floating a ) => Point a -> Point a -> a distPoints ( P x1 y1 ) ( P x2 y2 ) = ( x1 - x2 ) ^ 2 + ( y1 - y2 ) ^ 2 --rotating caliipers rotCal :: ( Num a , Ord a , Floating a ) => [ Point a ] -> a -> Int -> Int -> Vector a -> Vector a -> a -> Int -> a rotCal arr ang pa pb ca@( V ax ay ) cb@( V bx by ) dia n | ang > pi = dia | otherwise = rotCal arr ang' pa' pb' ca' cb' dia' n where P x1 y1 = arr !! pa P x2 y2 = arr !! ( mod ( pa + 1 ) n ) P x3 y3 = arr !! pb P x4 y4 = arr !! ( mod ( pb + 1 ) n ) t1 = angVectors ca ( V ( x2 - x1 ) ( y2 - y1 ) ) t2 = angVectors cb ( V ( x4 - x3 ) ( y4 - y3 ) ) ca' = rotVector ca $ min t1 t2 cb' = rotVector cb $ min t1 t2 ang' = ang + min t1 t2 pa' = if t1 < t2 then mod ( pa + 1 ) n else pa pb' = if t1 >= t2 then mod ( pb + 1 ) n else pb dia' = max dia $ distPoints ( arr !! pa' ) ( arr !! pb' ) --dia' = max dia $ if t1 < t2 then distPoints ( arr !! pa' ) ( arr !! pb ) else distPoints ( arr !! pb' ) ( arr !! pa ) solve :: ( Num a , Ord a , Floating a ) => [ Point a ] -> String solve [] = "0" solve [ p ] = "0" solve [ p1 , p2 ] = show $ distPoints p1 p2 solve [ p1 , p2 , p3 ] = show $ max ( distPoints p1 p2 ) $ max ( distPoints p2 p3 ) ( distPoints p3 p1 ) solve arr = show $ rotCal arr' 0 pa pb ( V 1 0 ) ( V (-1) 0 ) dia n where arr' = convexHull arr y1 = minimumBy ( \( P _ y1 ) ( P _ y2 ) -> compare y1 y2 ) arr' y2 = maximumBy ( \( P _ y1 ) ( P _ y2 ) -> compare y1 y2 ) arr' pa = fromJust . findIndex ( \ t -> t == y1 ) $ arr' pb = fromJust . findIndex ( \ t -> t == y2 ) $ arr' dia = distPoints ( arr' !! pa ) ( arr' !! pb ) n = length arr' --end of rotating caliper --spoj code for testing final :: ( Num a , Ord a , Floating a ) => [ Point a ] -> String final [] = "0" final [ p ] = "0" final [ p1 , p2 ] = show $ distPoints p1 p2 final [ p1 , p2 , p3 ] = show $ max ( distPoints p1 p2 ) $ max ( distPoints p2 p3 ) ( distPoints p3 p1 ) final arr = solve . convexHull $ arr format :: ( Num a , Ord a , Floating a ) => [ Int ] -> [ [ Point a ]] format [] = [] format (x:xs ) = t : format b where ( a , b ) = splitAt ( 2 * x ) xs t = helpFormat a where helpFormat [] = [] helpFormat ( x' : y' : xs' ) = ( P ( fromIntegral x' ) ( fromIntegral y' ) ) : helpFormat xs' readD :: String -> Int readD = read main = interact $ unlines . map final . format . concat . ( map . map ) readD . map words . tail . lines --end of spoj code |
aW1wb3J0IERhdGEuTGlzdAppbXBvcnQgRGF0YS5BcnJheQppbXBvcnQgRGF0YS5NYXliZQoKZGF0YSBQb2ludCBhID0gUCBhIGEgZGVyaXZpbmcgKCBTaG93ICwgT3JkICwgRXEgKSAKZGF0YSBWZWN0b3IgYSA9IFYgYSBhIGRlcml2aW5nICggU2hvdyAsIE9yZCAsIEVxICkgCmRhdGEgVHVybiA9IFMgfCBMIHwgUiBkZXJpdmluZyAoIFNob3cgLCBFcSAsIE9yZCAsIEVudW0gICkKCgotLXN0YXJ0IG9mIGNvbnZleCBodWxsCgpjb21wUG9pbnQgOjogKCBOdW0gIGEgLCBPcmQgYSApID0+IFBvaW50IGEgLT4gUG9pbnQgYSAtPiBPcmRlcmluZwpjb21wUG9pbnQgKCBQIHgxIHkxICkgKCBQIHgyIHkyICkKICB8IGNvbXBhcmUgeDEgeDIgPT0gRVEgPSBjb21wYXJlIHkxIHkyCiAgfCBvdGhlcndpc2UgPSBjb21wYXJlIHgxIHgyIAoKc29ydFBvaW50IDo6ICggTnVtIGEgLCBPcmQgYSApID0+IFsgUG9pbnQgYSBdIC0+IFsgUG9pbnQgYSBdCnNvcnRQb2ludCB4cyA9IHNvcnRCeSAoIFwgeCB5IC0+IGNvbXBQb2ludCB4IHkgKSB4cwoKZmluZFR1cm4gOjogKCBOdW0gYSAsIE9yZCBhICwgRXEgYSApID0+IFBvaW50IGEgLT4gUG9pbnQgYSAtPiBQb2ludCBhIC0+IFR1cm4KZmluZFR1cm4gKCBQIHgwIHkwICkgKCBQIHgxIHkxICkgKCBQIHgyIHkyICkKIHwgKCB5MSAtIHkwICkgKiAoIHgyLSB4MCApIDwgKCB5MiAtIHkwICkgKiAoIHgxIC0geDAgKSA9IEwKIHwgKCB5MSAtIHkwICkgKiAoIHgyLSB4MCApID09ICggeTIgLSB5MCApICogKCB4MSAtIHgwICkgPSBTCiB8IG90aGVyd2lzZSA9IFIgCgpodWxsQ29tcHV0YXRpb24gOjogKCBOdW0gYSAsIE9yZCBhICkgPT4gWyBQb2ludCBhIF0gLT4gWyBQb2ludCBhIF0gLT4gWyBQb2ludCBhIF0KaHVsbENvbXB1dGF0aW9uIFt4XSAoIHo6eXMgKSA9IGh1bGxDb21wdXRhdGlvbiBbeix4XSB5cwpodWxsQ29tcHV0YXRpb24geHMgW10gPSB4cwpodWxsQ29tcHV0YXRpb24gICggeSA6IHggOiB4cyApICggeiA6IHlzICkKICB8ICBmaW5kVHVybiB4IHkgeiA9PSBSID0gaHVsbENvbXB1dGF0aW9uICggeDp4cyApICggeiA6IHlzICkKICB8ICBmaW5kVHVybiB4IHkgeiA9PSBTID0gaHVsbENvbXB1dGF0aW9uICggeDp4cyApICggeiA6IHlzICkKICB8ICBvdGhlcndpc2UgPSBodWxsQ29tcHV0YXRpb24gKCB6IDogeSA6IHggOiB4cyApIHlzIAoKY29udmV4SHVsbCA6OiAoIE51bSBhICwgT3JkIGEgKSA9PiBbIFBvaW50IGEgXSAtPiBbIFBvaW50IGEgXQpjb252ZXhIdWxsIFtdID0gW10KY29udmV4SHVsbCBbIHAgXSA9ICBbIHAgXQpjb252ZXhIdWxsIFsgcDEgLCBwMiBdID0gWyBwMSAsIHAyIF0KY29udmV4SHVsbCB4cyA9IGZpbmFsIHdoZXJlCgl0eHMgPSBzb3J0UG9pbnQgeHMKCSggeCA6IHkgOiB5cyAgKSA9IHR4cwogICAgICAgIGxodWxsID0gaHVsbENvbXB1dGF0aW9uIFt5LHhdIHlzCgkoIHgnOiB5JyA6IHhzJyApID0gcmV2ZXJzZSB0eHMKCXVodWxsID0gaHVsbENvbXB1dGF0aW9uIFsgeScgLCB4JyBdIHhzJwoJZmluYWwgPSAoIGluaXQgbGh1bGwgKSArKyAoIGluaXQgdWh1bGwgKSAgCgotLWVuZCBvZiBjb252ZXggaHVsbCAKCgotLWRvdCBwcm9kdWN0IGZvciBnZXR0aW5nIGFuZ2xlCmFuZ1ZlY3RvcnMgOjogKCBOdW0gYSAsIE9yZCBhICwgRmxvYXRpbmcgYSApID0+IFZlY3RvciBhIC0+IFZlY3RvciBhIC0+IGEgCmFuZ1ZlY3RvcnMgKCBWIGF4IGF5ICkgKCBWIGJ4IGJ5ICkgPSB0aGV0YSB3aGVyZSAKICAgIGRvdCA9IGF4ICogYnggKyBheSAqIGJ5IAogICAgYSA9IHNxcnQgJCBheCBeIDIgKyBheSBeIDIgCiAgICBiID0gc3FydCAkIGJ4IF4gMiArIGJ5IF4gMiAKICAgIHRoZXRhID0gYWNvcyAkIGRvdCAvIGEgLyBiICAKCi0tc3RhcnQgb2Ygcm90YXRpbmcgY2FsaXBlciBwYXJ0IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUm90YXRpbmdfY2FsaXBlcnMKCi0tcm90YXRlIHRoZSB2ZWN0b3IgeCB5IGJ5IGFuZ2xlIHQgCnJvdFZlY3RvciA6OiAoIE51bSBhICwgT3JkIGEgLCBGbG9hdGluZyBhICkgPT4gVmVjdG9yIGEgLT4gYSAtPiBWZWN0b3IgYSAKcm90VmVjdG9yICggViB4IHkgKSB0ID0gViAoIHggKiBjb3MgdCAtIHkgKiBzaW4gdCApICggeCAqIHNpbiB0ICsgeSAqIGNvcyB0ICkgIAoKLS1zcXVhcmUgb2YgZGlzdCBiZXR3ZWVuIHR3byBwb2ludHMgCgpkaXN0UG9pbnRzIDo6ICggTnVtIGEgLCBPcmQgYSAsIEZsb2F0aW5nIGEgKSA9PiBQb2ludCBhIC0+IFBvaW50IGEgLT4gYQpkaXN0UG9pbnRzICggUCB4MSB5MSApICggUCB4MiB5MiApID0gICggeDEgLSB4MiApIF4gMiArICggeTEgLSB5MiApIF4gMiAKCi0tcm90YXRpbmcgY2FsaWlwZXJzIAoKcm90Q2FsIDo6ICggTnVtIGEgLCBPcmQgYSAsIEZsb2F0aW5nIGEgKSA9PiBbIFBvaW50IGEgXSAtPiBhIC0+IEludCAtPiBJbnQgLT4gVmVjdG9yIGEgLT4gVmVjdG9yIGEgLT4gYSAtPiBJbnQgLT4gYSAKcm90Q2FsIGFyciBhbmcgIHBhIHBiIGNhQCggViBheCBheSApIGNiQCggViBieCBieSApIGRpYSBuIAogICB8IGFuZyA+IHBpID0gZGlhIAogICB8IG90aGVyd2lzZSA9IHJvdENhbCBhcnIgYW5nJyBwYScgcGInIGNhJyBjYicgZGlhJyBuIHdoZXJlIAoJUCB4MSB5MSA9IGFyciAhISBwYQoJUCB4MiB5MiA9IGFyciAhISAoIG1vZCAoIHBhICsgMSApIG4gKQoJUCB4MyB5MyA9IGFyciAhISBwYiAKCVAgeDQgeTQgPSBhcnIgISEgKCBtb2QgKCBwYiArIDEgKSBuICkgCgl0MSA9IGFuZ1ZlY3RvcnMgY2EgKCBWICggeDIgLSB4MSApICggeTIgLSB5MSApICkKCXQyID0gYW5nVmVjdG9ycyBjYiAoIFYgKCB4NCAtIHgzICkgKCB5NCAtIHkzICkgKQoJY2EnID0gcm90VmVjdG9yIGNhICAkIG1pbiB0MSB0MiAKCWNiJyA9IHJvdFZlY3RvciBjYiAgJCBtaW4gdDEgdDIKCWFuZycgPSBhbmcgKyBtaW4gdDEgdDIgCglwYScgPSBpZiB0MSA8IHQyIHRoZW4gbW9kICggcGEgKyAxICkgbiBlbHNlIHBhIAoJcGInID0gaWYgdDEgPj0gdDIgdGhlbiBtb2QgKCBwYiArIDEgKSBuIGVsc2UgcGIKCWRpYScgPSBtYXggZGlhICQgZGlzdFBvaW50cyAoIGFyciAhISBwYScgKSAoIGFyciAhISBwYicgKSAKCS0tZGlhJyA9IG1heCBkaWEgICQgaWYgdDEgPCB0MiB0aGVuIGRpc3RQb2ludHMgKCBhcnIgISEgcGEnICkgKCBhcnIgISEgcGIgKSBlbHNlIGRpc3RQb2ludHMgKCBhcnIgISEgcGInICkgKCBhcnIgISEgcGEgKQoKCnNvbHZlIDo6ICggTnVtIGEgLCBPcmQgYSAsIEZsb2F0aW5nIGEgKSA9PiBbIFBvaW50IGEgXSAtPiBTdHJpbmcgCnNvbHZlIFtdID0gIjAiCnNvbHZlIFsgcCBdID0gIjAiCnNvbHZlIFsgcDEgLCBwMiBdID0gc2hvdyAkIGRpc3RQb2ludHMgcDEgcDIKc29sdmUgWyBwMSAsIHAyICwgcDMgXSA9IHNob3cgJCBtYXggKCBkaXN0UG9pbnRzIHAxIHAyICkgJCBtYXggKCBkaXN0UG9pbnRzIHAyIHAzICkgKCBkaXN0UG9pbnRzIHAzIHAxICkgCnNvbHZlIGFyciA9IHNob3cgJCByb3RDYWwgYXJyJyAwIHBhIHBiICggViAxIDAgKSAoIFYgKC0xKSAwICkgZGlhIG4gd2hlcmUgCgkgICBhcnInID0gIGNvbnZleEh1bGwgICBhcnIgCgkgICB5MSA9IG1pbmltdW1CeSAoIFwoIFAgXyB5MSApICggUCBfIHkyICkgLT4gY29tcGFyZSB5MSB5MiApIGFycicKCSAgIHkyID0gbWF4aW11bUJ5ICggXCggUCBfIHkxICkgKCBQIF8geTIgKSAtPiBjb21wYXJlIHkxIHkyICkgYXJyJwoJICAgcGEgPSBmcm9tSnVzdCAuIGZpbmRJbmRleCAoIFwgdCAtPiB0ID09IHkxICkgJCBhcnInIAoJICAgcGIgPSBmcm9tSnVzdCAuIGZpbmRJbmRleCAoIFwgdCAtPiB0ID09IHkyICkgJCBhcnInIAoJICAgZGlhID0gZGlzdFBvaW50cyAoIGFycicgISEgcGEgKSAoIGFycicgISEgcGIgKSAKCSAgIG4gPSBsZW5ndGggYXJyJwoKIC0tZW5kIG9mIHJvdGF0aW5nIGNhbGlwZXIgCgotLXNwb2ogY29kZSBmb3IgdGVzdGluZyAKZmluYWwgOjogKCBOdW0gYSAsIE9yZCBhICwgRmxvYXRpbmcgYSApID0+IFsgUG9pbnQgYSBdIC0+IFN0cmluZwpmaW5hbCBbXSA9ICIwIgpmaW5hbCBbIHAgXSA9ICIwIgpmaW5hbCBbIHAxICwgcDIgXSA9IHNob3cgJCBkaXN0UG9pbnRzIHAxIHAyCmZpbmFsIFsgcDEgLCBwMiAsIHAzIF0gPSBzaG93ICQgbWF4ICggZGlzdFBvaW50cyBwMSBwMiApICQgbWF4ICggZGlzdFBvaW50cyBwMiBwMyApICggZGlzdFBvaW50cyBwMyBwMSApCmZpbmFsIGFyciA9IHNvbHZlIC4gY29udmV4SHVsbCAkIGFycgoKZm9ybWF0IDo6ICggTnVtIGEgLCBPcmQgYSAsIEZsb2F0aW5nIGEgKSA9PiBbIEludCBdIC0+IFsgWyBQb2ludCBhIF1dCmZvcm1hdCBbXSA9IFtdCmZvcm1hdCAoeDp4cyApID0gIHQgOiBmb3JtYXQgYiAgd2hlcmUgCgkoIGEgLCBiICkgPSBzcGxpdEF0ICggMiAqIHggKSB4cyAKCXQgPSBoZWxwRm9ybWF0IGEgd2hlcmUgCgkgICAgaGVscEZvcm1hdCBbXSA9IFtdCQoJICAgIGhlbHBGb3JtYXQgKCB4JyA6IHknIDogeHMnICkgPSAoIFAgKCBmcm9tSW50ZWdyYWwgeCcgKSAoIGZyb21JbnRlZ3JhbCAgeScgKSApIDogaGVscEZvcm1hdCB4cycKCnJlYWREIDo6IFN0cmluZyAtPiBJbnQKcmVhZEQgPSByZWFkIAoKCm1haW4gPSBpbnRlcmFjdCAkIHVubGluZXMgLiBtYXAgIGZpbmFsIC4gZm9ybWF0IC4gY29uY2F0IC4gKCBtYXAgLiBtYXAgKSByZWFkRCAuIG1hcCB3b3JkcyAuIHRhaWwgIC4gbGluZXMgIAoKLS1lbmQgb2Ygc3BvaiBjb2RlIA==
[1 of 1] Compiling Main ( prog.hs, prog.o ) Linking prog ...
-
upload with new input
-
result: Success time: 0s memory: 3820 kB returned value: 0
5 1 2 -3 4 0 0 -2 2 2 2 1 0 6 -4 2 2 2 5 0 0 5 6 1 -1 -1 10 0 0 5 1 9 2 12 3 14 4 15 5 16 7 17 10 18 14 19 19 10 2 -3 -1 2 0 5 -5 -1 -4 2 4 0 1 3 4 3 -3 -4 0 -2
0 16.0 101.0 722.0 97.0
-
result: Success time: 0s memory: 3820 kB returned value: 1
prog: Prelude.tail: empty list


