Bagilah dan tetaplah Bahagia. Siapa yang peduli dengan bagian Penaklukkan?

12

Nah, ketika saya membeli hadiah untuk dua istri saya, saya ingin mereka merasa sama pentingnya bagi saya, tetapi sulit untuk pergi berbelanja dengan anggaran tetap. Sebagai gantinya, saya membeli banyak barang dan membaginya menjadi dua kelompok dengan nilai yang sama mungkin. Lalu saya membeli banyak cokelat untuk memperbaiki sisanya.

Tetapi saya tidak ingin melakukan semua yang sulit ketika komputer saya dapat melakukannya. Dan kamu juga tidak. Jadi selesaikan masalah ini sehingga pada saat Anda perlu membagi hadiah di antara istri Anda, Anda tahu itu akan mudah.

Memasukkan

1 array elemen (N * 2) di mana N * 2 ditentukan pada baris pertama.
Elemen-elemen array di baris berikut.

Keluaran

2 array elemen N masing-masing sedemikian rupa sehingga:
Perbedaan (Jumlah elemen array 1) dan (Jumlah elemen array 2) sedekat mungkin dengan 0.

Contoh

Memasukkan

4
1 2 3 4 

Keluaran

1 4
2 3
diff=0

Penafian : Saya tidak punya dua istri. Tetapi ketika saya merasa buruk, saya membayangkan memiliki dua istri. Dan tiba-tiba, saya bersyukur dan senang bahwa saya hanya punya satu. : D

rahulroy9202
sumber
3
Seperti berdiri, "2 array elemen N masing-masing" memaksa kelompok-kelompok untuk juga berukuran sama. Apakah ini dimaksudkan? Misalnya pada saat ini untuk grup input 1 1 1 1 1 5jawaban yang benar adalah 1 1 1| 1 1 5, sementara 1 1 1 1 1| 5akan lebih masuk akal.
shiona
Kira masalahnya juga berlaku untuk anak kembar dan mungkin untuk anak-anak lain - rasi bintang juga. Natal hari ini sebagian besar adalah acara 'dia mendapat lebih dari saya' ...
TheConstructor
1
@shiona, ya, ukuran yang sama dimaksudkan. @ TheConstructor, membagi di antara anak-anak tidak semanis membagi di antara dua istri. : D
rahulroy9202
Tantangan kode tag membutuhkan kriteria kemenangan yang objektif. Juga terkait erat dengan masalah jumlah himpunan bagian yang diminta di sini sebelumnya.
Howard
@Howard ada perbedaan penting untuk subset jumlah: Anda perlu membangun dua daftar ukuran yang sama (tidak hanya sama-sama dihargai), Anda perlu menggunakan semua elemen, ...
TheConstructor

Jawaban:

4

Jawa

Mencoba memecahkan masalah ini dalam dua fase:

  1. Buat dua daftar berukuran sama dengan menambahkan yang terbesar tersisa ke daftar yang lebih kecil saat ini dan yang berikutnya. Ulang.
  2. Identifikasi item dari kedua daftar yang dapat diubah untuk mengurangi perbedaan nilai

Masukan seperti

8
1 2 3 4 5 6 7 8

sudah diselesaikan setelah fase 1 sebagai contoh

2 3 5 8
1 4 6 7
diff=0

dan masukan suka

6
1 4 5 6 7 8

akan membutuhkan kedua fase sehingga

1 5 8
4 6 7
diff=3

(setelah fase satu) menjadi hasil dari

1 6 8
4 5 7
diff=1

Meskipun saya dapat menjamin upaya ini akan selalu memberikan solusi, saya tidak dapat membuktikan bahwa solusi optimal ditemukan dalam semua kasus. Dengan pembatasan daftar ukuran yang sama itu terasa cukup realistis bahwa tidak ada kasus sudut tertinggal. Buktikan bahwa aku salah ;-)

Program di ideone.com

import java.util.*;

/**
 * Created to solve http://codegolf.stackexchange.com/q/23461/16293 .
 */
public class EqualSums {

    public static void main(String[] args) {
        final Scanner s = new Scanner(System.in);
        // Read number of elements to divide
        final int count = s.nextInt();
        if (count % 2 == 1) {
            throw new IllegalStateException(count + " can not be divided by 2. Consider adding a 0 value.");
        }
        // Read the elements to divide
        final SortedList valueStack = new SortedList(count);
        for (int i = 0; i < count; i++) {
            valueStack.add(s.nextLong());
        }

        final SortedList targetOne = new SortedList(count / 2);
        final SortedList targetTwo = new SortedList(count / 2);
        // Divide elements into two groups
        addInPairs(targetOne, targetTwo, valueStack);
        // Try to ensure groups have equal value
        retaliate(targetOne, targetTwo);

        // Output result
        System.out.println(targetOne);
        System.out.println(targetTwo);
        System.out.println("diff=" + Math.abs(targetOne.getSum() - targetTwo.getSum()));
    }

    private static void addInPairs(SortedList targetOne, SortedList targetTwo, SortedList valueStack) {
        SortedList smallerTarget = targetOne;
        SortedList biggerTarget = targetTwo;
        while (!valueStack.isEmpty()) {
            // Add biggest remaining value to small target
            smallerTarget.add(valueStack.removeLast());

            // Add second biggest remaining value to big target
            biggerTarget.add(valueStack.removeLast());

            // Flip targets if roles have changed
            if (smallerTarget.getSum() > biggerTarget.getSum()) {
                final SortedList temp = smallerTarget;
                smallerTarget = biggerTarget;
                biggerTarget = temp;
            }
        }

    }

    private static void retaliate(SortedList targetOne, SortedList targetTwo) {
        long difference;
        boolean changed;
        outer:
        do {
            difference = Math.abs(targetOne.getSum() - targetTwo.getSum());
            if (difference == 0) {
                return;
            }
            changed = false;
            // Try to find two values, that reduce the difference by changing them between targets
            for (Long valueOne : targetOne) {
                for (Long valueTwo : targetTwo) {
                    final Long tempOne = targetOne.getSum() + valueTwo - valueOne;
                    final Long tempTwo = targetTwo.getSum() - valueTwo + valueOne;
                    if (Math.abs(tempOne - tempTwo) < difference) {
                        targetOne.remove(valueOne);
                        targetTwo.add(valueOne);
                        targetTwo.remove(valueTwo);
                        targetOne.add(valueTwo);
                        changed = true;
                        continue outer;
                    }
                }
            }
        } while (changed);
    }

    public static class SortedList extends AbstractList<Long> {

        private final ArrayList<Long> list;
        private long sum = 0;

        public SortedList(int count) {
            list = new ArrayList<>(count);
        }

        // the next functions access list-field directly
        @Override
        public Long get(int index) {
            return list.get(index);
        }

        @Override
        public boolean add(final Long t) {
            final int i = Collections.binarySearch(list, t);
            if (i < 0) {
                // No equal element present
                list.add(-i - 1, t);
            } else {
                list.add(afterLastEqual(i, t), t);
            }
            sum += t;
            return true;
        }

        @Override
        public Long remove(int index) {
            final Long old = list.remove(index);
            sum -= old;
            return old;
        }

        @Override
        public int size() {
            return list.size();
        }

        // the next functions access list-field only through the functions above this point
        // to ensure the sum is well kept

        public long getSum() {
            return sum;
        }

        private int afterLastEqual(final int start, Object o) {
            int found = start;
            while (found < size() && o.equals(get(found))) {
                found++;
            }
            return found;
        }

        private int beforeFirstEqual(final int start, final Object o) {
            int found = start;
            while (found >= 0 && o.equals(get(found))) {
                found--;
            }
            return found;
        }

        @Override
        public int indexOf(Object o) {
            try {
                final int i = Collections.binarySearch(this, (Long) o);
                if (i >= 0) {
                    return beforeFirstEqual(i, o) + 1;
                }
            } catch (ClassCastException e) {
                // Object was not instance of Long
            }
            return -1;
        }

        @Override
        public int lastIndexOf(Object o) {
            try {
                final int i = Collections.binarySearch(this, (Long) o);
                if (i >= 0) {
                    return afterLastEqual(i, o) - 1;
                }
            } catch (ClassCastException e) {
                // Object was not instance of Long
            }
            return -1;
        }

        @Override
        public boolean remove(Object o) {
            if (o == null) {
                return false;
            }
            final int i = indexOf(o);
            if (i >= 0) {
                remove(i);
                return true;
            }
            return false;
        }

        public Long removeLast() {
            return remove(size() - 1);
        }

        public Long removeFirst() {
            return remove(0);
        }

        @Override
        public String toString() {
            Iterator<Long> it = iterator();
            if (!it.hasNext()) {
                return "";
            }

            StringBuilder sb = new StringBuilder();
            for (; ; ) {
                Long e = it.next();
                sb.append(e);
                if (!it.hasNext()) {
                    return sb.toString();
                }
                sb.append(' ');
            }
        }
    }
}
Korektor
sumber
3

Brachylog 2

pᶠḍᵐ{+ᵐo-}ᵒh

Cobalah online!

Ini adalah kontes popularitas, tetapi itu tidak selalu berarti bahwa bahasa golf tidak cocok. (Sungguh, saya seharusnya menjawab di Jelly karena jawaban Jelly cenderung mendapatkan jumlah upvotes yang tidak proporsional untuk beberapa alasan terlepas dari siapa yang mengirimkannya atau seberapa pegolf mereka, tetapi Brachylog lebih mudah dibaca.)

Kami memulai dengan mengambil daftar semua permutasi dari input ( pᶠ), dan membelah masing-masing ( ) menjadi dua bagian yang sama ( ; kami bisa memberikannya subskrip jika Anda memiliki lebih dari dua istri karena suatu alasan). Kemudian kami memesan permutasi split ( {…}ᵒ) dengan mengambil jumlah ( +) dari masing-masing ( ) setengah, mengambil perbedaan absolut (yaitu o-, "memerintahkan perbedaan"), dan menggunakan perbedaan tersebut untuk menentukan urutan pengurutan. Hasil terbaik adalah yang pertama, jadi kami mengambil kepala daftar dengan huntuk mendapatkan hasilnya.


sumber
2

Mathematica

Formulir input

String input harus diambil melalui STDIN. assetsmengacu pada jumlah yang akan didistribusikan di antara para istri (atau kembar). lengthadalah jumlah aset.

assets=ToExpression[Rest[s=StringSplit[input]]]
length=ToExpression[First[s]]

Untuk tujuan saat ini kami akan mengasumsikan bahwa aset terdiri dari bilangan bulat dari 1 hingga 20.

assets=Range[20];
length=Length[Range[20]]

Pengolahan

(* find all possible distributions to one wife; the other presumably gets the remaining assets *)
r=Subsets[assets,{length/2}];

(*order them according to the difference with respect to the total of half of the assets. 
Remove the first set of assets.  One wife will get these.*)
s=SortBy[r/.{{a__Integer}:> {{a},Abs[Tr[Range[20]/2]-Tr[{a}]]}},Last][[1]];

(*The other wife's assets will be the complement.  The difference is carried over from the sorting routine. *)
Grid[{{Grid[{s[[1]],Complement[assets,s[[1]]]}]},{"difference = "<>ToString[s[[2]]]}}]

r20


Apakah distribusinya tidak adil? Jadi, pilih yang lain.

@The Constructor mencatat bahwa istri 2 dapat menentang fakta bahwa istri 1 mendapatkan semua aset terbaik. Jadi yang berikut ini menghasilkan semua saham "adil" (perbedaan = perbedaan terendah) untuk istri 1; istri 2 mendapatkan aset yang tersisa; nol mengacu pada perbedaan aset untuk para istri. Ada 5448 cara untuk mendistribusikan aset berbobot 1 hingga 20. Hanya beberapa baris yang ditampilkan.

Formatnya adalah

s=SortBy[r/.{{a__Integer}:> {{a},Abs[Tr[Range[20]/2]-Tr[{a}]]}},Last];
z=Cases[s,{_List,x_}/;x==s[[1,2]]];
Short[z,10]
Length[z]

{{{1,2,3,4,5,16,17,18,19,20}, 0}, {{1,2,3,4,6,15,17,18,19,20}, 0}, {{1,2,3,4,7,14,17,18,19,20}, 0}, {{1,2,3,4,7,15,16,18,19,20 }, 0}, {{1,2,3,4,8,13,17,18,19,20}, 0}, {{1,2,3,4,8,14,16,18,19 , 20}, 0}, {{1,2,3,4,8,15,16,17,19,20}, 0}, {{1,2,3,4,9,12,17,18 , 19,20}, 0}, {{1,2,3,4,9,13,16,18,19,20}, 0}, {{1,2,3,4,9,14,15 , 18,19,20}, 0}, {{1,2,3,4,9,14,16,17,19,20}, 0}, {{1,2,3,4,9,15 , 16,17,18,20}, 0}, {{1,2,3,4,10,11,17,18,19,20}, 0}, {{1,2,3,4,10 , 12,16,18,19,20}, 0}, <<5420>>, {{5,6,7,8,9,11,13,14,15,17}, 0}, {{5 , 6,7,8,9,12,13,14,15,16}, 0}, {{5,6,7,8,10,11,12,13,13,14,19}, 0}, { {5,6,7,8,10,11,12,13,15,18}, 0}, {{5,6,7,8,10,11,12,13,16,17}, 0} , {{5,6,7,8,10,11,12,14,15,17}, 0}, {{5,6,7,8,10,11,13,14,15,16}, 0}, {{5,6,7,9,10,11,12,13,14,18}, 0}, {{5,6,7,9,10,11,12,13,15,17 }, 0}, {{5,6,7,9,10,11,12,14,15,16}, 0}, {{5,6,8,9,10,11,12,13,14 , 17}, 0}, {{5,6,8,9,10,11,12,13,15,16}, 0}, {{5,7,8,9,10,11,12,13,14,16}, 0}, {{6,7,8,9,10,11,12,13,14,15}, 0}}

5448


Pengajuan sebelumnya dapat ditemukan di antara suntingan. Itu jauh lebih tidak efisien, bergantung seperti yang dilakukannya Permutations.

DavidC
sumber
Mathematica tampak cantik untuk tugas seperti itu. Satu hal terakhir adalah bahwa istri sejati mungkin akan berdebat karena 5 item paling berharga semuanya ada di satu tumpukan. (Ya, dengan 1 hingga 20 tidak ada solusi tanpa ruang untuk argumen)
TheConstructor
@ Sebenarnya, ada beberapa cara untuk mendistribusikan aset. Saya mendaftarkan beberapa cara dalam sebuah lampiran. Catatan: Hanya aset satu istri yang terdaftar; yang lain mendapat komplemen.
DavidC
Itulah salah satu alasan saya memilih untuk membangun tumpukan inital saya seperti yang saya lakukan: jadi biasanya dua hal yang paling berharga tidak berada di tumpukan yang sama. Solusi awal Anda membuktikan bahwa ada 10 pasang angka dengan jumlah 21; Anda secara implisit memilih pasangan berurutan.
TheConstructor
Ya, saya menghargai logika pendekatan Anda.
DavidC
2

J

Ada lembar contekan semua primitif J di tautan ini , jika Anda ingin mengikuti di rumah. Ingat: J umumnya dibaca dari kanan ke kiri, jadi itu 3*2+1adalah 7, bukan 9. Setiap kata kerja (J untuk fungsi) adalah monadik, jadi di depan suka f y, atau diad, jadi di antara suka x f y.

N =: (". 1!:1 ] 1) % 2          NB. number of items per wife
S =: ". 1!:1 ] 1                NB. list of items to distribute

bins =: #: i. 2 ^ 2*N           NB. all binary strings of length 2n
even =: bins #~ N = +/"1 bins   NB. select those with row-sum 1

NB. all distributions of equal numbers of items to each wife
NB. resultant shape: a list of 2xN matrices
NB. this /. adverb is where all the magic happens, see below
dist =: even ]/."1 S

diff =: | -/"1 +/"1 dist        NB. difference in wives' values
idx  =: (i. <./) diff           NB. index of the lowest difference

1!:2&2 idx { dist               NB. print the winning distribution of items
1!:2&2 'diff=', idx { diff      NB. and the difference of that distribution

Catatan dan penjelasan:

  • u/berarti "lipat u", jadi lakukan operasi biner di atas setiap elemen dalam daftar. Jadi misalnya: +/berarti Lipat Plus , atau Jumlah ; <.adalah Lesser Of , jadi <./berarti Fold Lesser Of , atau Minimum .

  • u"1berarti "tampil udi sel 1 dimensi", yaitu di atas setiap baris. Biasanya kata kerja dalam J adalah atom, atau berlaku untuk seluruh argumen. Ini berlaku untuk kedua argumen jika kata kerjanya digunakan secara dua arah (dengan dua argumen). Pertimbangkan yang berikut ini:

       i. 2 3        NB. just a 2x3 matrix of numbers
    0 1 2
    3 4 5
       +/   i. 2 3   NB. Sum the items
    3 5 7
       +/"1 i. 2 3   NB. Sum the items of each row
    3 12
    
  • #:adalah kata kerja yang memperluas angka ke representasi binernya. Ketika Anda menggunakannya pada daftar dengan lebih dari satu elemen, itu juga akan menyelaraskan semua angka dengan benar, sehingga Anda #:i.2^nakan mendapatkan setiap string panjang biner n.

  • /., bila digunakan secara dua arah, disebut Kunci . Menggunakan elemen daftar di sisi kiri sebagai kunci, dan yang di sisi kanan sebagai nilai. Ini mengelompokkan setiap set nilai yang berbagi kunci, dan kemudian melakukan beberapa operasi pada mereka.

    Dalam kasus ]/., operasi hanyalah kata kerja identitas, jadi tidak ada yang sama sekali istimewa yang terjadi di sana, tetapi fakta bahwa /.akan membagi daftar bagi kita adalah bagian yang penting. Inilah sebabnya kami membuat daftar biner: sehingga untuk setiap daftar ( "1), kami dapat membagi hadiah untuk para istri dengan semua cara yang memungkinkan.

  • 1!:1]1dan 1!:2&2merupakan operasi read-in dan write-out. Bagian 1!:nadalah kata kerja dan nomor lainnya adalah pegangan file. 1adalah konsol masuk, 2konsol keluar, dan 3 4 5stdin, stdout, dan stderr. Kami juga menggunakan ".saat membaca sehingga kami mengubah string input menjadi angka.

algoritme hiu
sumber
1
+1 untuk mengirimkan jawaban dalam J dan AT TRYING SETIDAKNYA agar dimengerti.
Level River St
1

Clojure

(defn divide [n]
 (loop [lv [] rv [] d (reverse (sort n))]
  (if (empty? d)
   [lv rv]
   (if (> (reduce + lv) (reduce + rv))
     (if (>= (count lv ) (count rv))
       (recur lv (conj rv (first d)) (into [] (rest d)))
       (recur (conj lv (last d)) rv (pop d))) 
     (if (<= (count lv ) (count rv))
       (recur (conj lv (first d)) rv (into [] (rest d)) )
       (recur lv (conj rv (last d)) (pop d)))))))


 (defn display [[f s]]
   (println f)
   (println s)
   (println (str "Diff " (- (reduce + f) (reduce + s)))))

Uji

 (->> 
 [5 1 89 36 2 -4 20 7]
 divide 
 display)


 =: [89 -4 1 2]
    [36 20 7 5]
    Diff 20
Mamun
sumber
Set hasil harus berukuran sama dan perbedaan antara nilai-nilai di dalam setiap set harus dicetak. Dilihat oleh hasil tes cepat pada ideone Anda mungkin telah melewatkan kedua poin
TheConstructor
tambahkan metode tampilan untuk mencetak hasil.
Mamun
Hasil ditetapkan sekarang ukurannya sama
Mamun
Untuk [1 4 5 6 7 8]program Anda dihitung di [8 5 4] [7 6 1] Diff 3mana solusi jelas dengan perbedaan 1 ada.
TheConstructor
1

MATLAB

Inilah solusi saya:

%input array
presents=zeros(2,8);
presents(1,1)=8; %number of presents
presents(2,:)=[1 2 7 4 5 3 2 8]; %list of presents

%calculate the cumulative sum of all permutations
%its all about the gift values
how_many=presents(1,1);
options=perms(presents(2,:);
subtotals=cumsum(options,2);

%find the first index where the difference between the two parts is minimal
%makes both wives happy!!
[~, double_happiness] = min(abs(sum(presents(2,:))/2-subtotals(:,how_many/2)));

%create the present lists for Jennifer and Kate :)
for_jennifer=options(double_happiness,1:how_many/2)
for_kate=options(double_happiness,how_many/2+1:end)

Sebagai contoh, daftar sekarang dalam kode sumber saya menghasilkan:

for_jennifer =

     8     2     5     1


for_kate =

     4     7     2     3

yang keduanya 16.

Jika saya golf kode saya, yang kurang menyenangkan saya mendapatkan karakter yang sangat tidak dioptimalkan. Kalahkan itu ;)

function f(p);o=perms(p(:,2));s=cumsum(o,2);[~,d]=min(abs(sum(p(:,2))/2-s(:,p(1,1)/2)));a={o(d,1:p(1,1)/2);o(d,p(1,1)/2+1:end)};a{:}
mmumboss
sumber
Array input harus berbentuk persegi.
DavidC
Tidak, tidak persegi? Tetapi sekarang saya melihat jumlah item harus di baris pertama. Saya akan mengubahnya.
mmumboss
0

PHP

Peringatan: Kode sangat kotor
Ia mencoba setiap kemungkinan permutasi dari input array.

Sampel ideone untuk 4/1 2 3 4: http://ideone.com/gIi174

<?php
// Discard the first input line! It's useless :)
fgets(STDIN);
$numbers = explode(' ', rtrim(fgets(STDIN)));
$valuePerWife = array_sum($numbers) / 2;

// Taken from here: http://stackoverflow.com/a/13194803/603003
// Credits to dAngelov: http://stackoverflow.com/users/955185/dangelov
function pc_permute($items, $perms = array( )) {
    if (empty($items)) {
        $return = array($perms);
    }  else {
        $return = array();
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
         list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             $return = array_merge($return, pc_permute($newitems, $newperms));
         }
    }
    return $return;
}


foreach (pc_permute($numbers) as $permutation) {
    $sum = 0;
    $rest = [];

    for ($i=0; $i<count($permutation); $i++) {
        $sum += $permutation[$i];
        if ($sum == $valuePerWife) {
            $rest = array_slice($permutation, $i + 1);
            break;
        }
    }

    if (array_sum($rest) == $valuePerWife) {
        echo implode(' ', array_slice($permutation, 0, $i + 1)), "\n";
        echo implode(' ', array_slice($permutation, $i + 1)), "\n";
        echo 'diff=0';
        exit;
    }
}
exit('DIDNT FOUND ANY COMBINATION!');
ComFreek
sumber
0

Python:

import itertools as t
raw_input()
a=[int(i) for i in raw_input().split()]
a=list(t.permutations(a))
b=len(a[0])/2
c=[(d[b:],d[:b]) for d in a]
d=[abs(sum(d[b:])-sum(d[:b])) for d in a]
e=zip(d,c)
e.sort()
print " ".join([str(i) for i in e[0][1][0]])
print " ".join([str(i) for i in e[0][1][1]])
print "diff",e[0][0]

atau sedikit golf:

import itertools as t
b=int(raw_input())/2
e=[(abs(sum(d[b:])-sum(d[:b])),(d[b:],d[:b])) for d in t.permutations([int(i) for i in raw_input().split()])]
e.sort()
f=e[0]
g=f[1]
print " ".join([str(i) for i in g[0]]),"\n"," ".join([str(i) for i in g[1]]),"\n","diff=",f[0]

Atau bahkan lebih jauh golf, karena setengah dari garis-garis hanya makeup. (dengan asumsi saya bisa membuang array internal yang mentah, karena ini tidak ditentukan dalam op) Anda dapat meninggalkan printin (misalnya) shell interaktif, dan menambahkan [::-1](pada akhir, setelah [0]) jika Anda benar-benar ingin diff terakhir.

import itertools as t
b=int(raw_input())/2
print sorted([(abs(sum(d[b:])-sum(d[:b])),(d[b:],d[:b])) for d in t.permutations([int(i) for i in raw_input().split()])])[0]

(hasil dalam (0, ((1, 2, 7, 8), (3, 4, 5, 6))))

Namun, ini hanya memaksa semua kombinasi yang memungkinkan, dan tidak boleh dianggap efisien dari jarak jauh. Namun, jika daftar yang panjangnya sama tidak masalah, ini juga akan berfungsi (pada array besar):

raw_input()
a,b=[],[]
for i in sorted([int(i) for i in raw_input().split()])[::-1]:
    b.append(i)
    if sum(b)>sum(a): b,a=a,b
print a,b,abs(sum(b)-sum(a))

Dengan kode di bawah ini misalnya, ini berjalan dengan sedikit perbedaan: 500k pada 10 ^ 10 nilai maks tidak banyak, jadi bisa dikatakan. Ini juga jauh lebih cepat: di mana kode lain mungkin tidak akan selesai dalam waktu kurang dari setahun (dan itu sangat optimis), ini berjalan sekitar setengah detik, meskipun jarak tempuh Anda mungkin berbeda.

def raw_input():
    import random
    return " ".join([str(random.randint(1,10**10)) for _ in range(10000)])

raw_input()
a,b=[],[]
for i in sorted([int(i) for i in raw_input().split()])[::-1]:
    b.append(i)
    if sum(b)>sum(a): b,a=a,b
print a,b,abs(sum(b)-sum(a))
Synthetica
sumber
Pertanyaan: Mengapa ini posting CW?
HyperNeutrino
0

Paham Haskell

> import Data.List
> import Data.Function

Saya menggunakan daftar monad untuk membaginya.

> divide []=return ([], [])
> divide (x:xs)=do
>   (w1, w2) <- divide xs
>   [(x:w1, w2), (w1, x:w2)]

Lalu kami membuat penilai.

> rating (w1, w2)=abs $ (sum w1) - (sum w2)

Dan kemudian fungsi yang akan meminimalkan perbedaan.

> best = minimumBy (compare `on` rating) . filter (\(x,y)->length x == length y)

Dan sesuatu yang menggabungkan semuanya.

> bestDivison=best . divide

Selanjutnya parser.

> parse::String->[Int]
> parse=fmap read . words

Dan formatter output.

> output (w1,w2)=unlines [unwords (map show w1)
>                        , unwords ( map show w2)
>                        , "diff="++(show $ abs $ (sum w1) - (sum w2))]

Dan sekarang programnya

> main = do
>   getLine --Ignored, I don't need the arrays length
>   input <- fmap parse getLine
>   putStrLn "" --For readability
>   putStrLn $ output $ bestDivison input

Contoh:

λ <*Main>: main
8
5 1 89 36 2 -4 20 7

5 36 20 7
1 89 2 -4
diff=20
PyRulez
sumber
Kumpulan hasil harus berukuran sama
TheConstructor