Böl ve Mutlu Kal. Conquer bölümünü kim önemsiyor?


12

İki eşim için hediye aldığımda, kendim için aynı derecede önemli hissetmelerini istiyorum, ancak sabit bütçelerle alışverişe gitmek zor. Bunun yerine, bir sürü şey satın alıyorum ve onları mümkün olduğunca eşit değere sahip iki gruba ayırıyorum. Sonra gerisini düzeltmek için bir demet çikolata satın alıyorum.

Ancak bilgisayarımın yapabileceği her şeyi yapmak istemiyorum. Ve sen de yapmıyorsun. Bu sorunu bir dahaki sefere eşleriniz arasında bir daha bölmeniz gerektiğinde kolay olacağını biliyorsunuz.

Giriş

1. satırda N * 2 belirtildiği 1 dizi (N * 2) eleman.
Aşağıdaki satırdaki dizinin elemanları.

Çıktı

Her biri 2 elemandan oluşan N dizisi:
Fark (Dizi 1 elemanlarının toplamı) ve (Dizi 2 elemanlarının toplamı) farkı 0'a mümkün olduğunca yakındır.

Misal

Giriş

4
1 2 3 4 

Çıktı

1 4
2 3
diff=0

Feragatname : İki eşim yok. Ama kendimi kötü hissettiğimde, iki karım olduğunu hayal ediyorum. Ve aniden, sadece bir tane olduğum için minnettar ve mutluyum. : D


3
Haliyle "her biri 2 eleman N dizisi", grupları da aynı boyutta olmaya zorlar. Bu amaçlandı mı? Örneğin, şu anda giriş grubu 1 1 1 1 1 5için doğru cevap 1 1 1| 1 1 5, süre 1 1 1 1 1| 5daha mantıklı olurdu.
shiona

Sanırım sorun ikizler ve muhtemelen diğer çocuk takımyıldızları için de geçerlidir. Bugün Noel çoğunlukla 'benden daha fazlasını aldı' etkinliği ...
TheConstructor

1
@ shiona, evet, eşit büyüklükte. @ Yapıcı, çocuklar arasında bölmek iki eş arasında bölmek kadar komik değil. : D
rahulroy9202

Tag -challenge etiketi , objektif kazanma kriteri gerektirir. Ayrıca burada daha önce sorulan alt küme toplamı problemi ile yakından ilgilidir .
Howard

@Altüm toplamı için önemli farklılıklar olmasına rağmen: iki eşit boyutta liste oluşturmanız gerekir (sadece eşit derecede değerli değil), tüm öğeleri kullanmanız gerekir ...
TheConstructor

Yanıtlar:


4

Java

Bu sorunu iki aşamada çözmeye çalışmak:

  1. Kalan en büyük olanı daha küçük listeye ve diğerini diğerine ekleyerek eşit boyutta iki liste oluşturun. Tekrar et.
  2. Değer farkını azaltmak için her iki listeden de değiştirilebilen öğeleri tanımlayın

Gibi giriş

8
1 2 3 4 5 6 7 8

faz 1'den sonra, örneğin

2 3 5 8
1 4 6 7
diff=0

ve girdi gibi

6
1 4 5 6 7 8

her iki aşamaya da ihtiyaç duyacak

1 5 8
4 6 7
diff=3

(birinci aşamadan sonra) sonucu

1 6 8
4 5 7
diff=1

Bu girişimin her zaman bir çözüm sağlayacağını garanti ederken, her durumda en uygun çözümün bulunduğunu kanıtlayamıyorum. Eşit büyüklükteki listelerin kısıtlanmasıyla geride hiçbir köşe vakası kalmaması oldukça gerçekçi. Yanıldığımı ispat et ;-)

Programı 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(' ');
            }
        }
    }
}

3

Brachylog 2

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

Çevrimiçi deneyin!

Bu bir popülerlik yarışmasıdır, ancak bu, golf dillerinin kötü bir uyum olduğu anlamına gelmez. (Gerçekten, Jelly'de cevaplamalıydım çünkü Jelly cevapları, onları kimin gönderdiğine veya ne kadar golf oynadıklarına bakılmaksızın, bir nedenden dolayı orantısız sayıda upvote alma eğilimindedir, ancak Brachylog daha okunabilir.)

Girdi ( pᶠ) ' nin tüm permütasyonlarının listesini alarak ve her ( )' i iki eşit parçaya bölerek işe başlarız ( ; herhangi bir nedenle ikiden fazla eşiniz varsa bir abonelik verebiliriz). Daha sonra bölünmüş permütasyonları ( {…}ᵒ) +her ( ) yarısının toplamını ( ) alarak, mutlak farkı (yani o-, "sıralı fark") alarak ve sıralama düzenini tanımlamak için bu farklılıkları kullanarak sipariş veririz. En iyi sonuç ilk sonuçtur, bu yüzden hsonucu almak için listenin başını alırız .


2

Mathematica

Giriş formları

Giriş dizesi STDIN üzerinden alınacaktır. assets"Kardeşler" eşler (veya ikizler) arasında dağıtılacak miktarları ifade eder. lengthvarlık sayısıdır.

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

Mevcut amaçlar için, varlıkların 1 ile 20 arasındaki tamsayılardan oluştuğunu varsayacağız.

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

İşleme

(* 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


Dağıtım adil değil mi? Yani, başka bir tane seçin.

@Yapıcı, 2 karısının, 1 karısının en iyi varlıklara sahip olduğuna itiraz edebileceğini kaydeder. Böylece aşağıdaki eş 1 için tüm "adil" (fark = en düşük fark) hisse üretir; karısı 2 kalan varlıkları alır; sıfır, eşlerin varlıklarındaki farkı ifade eder. 1'den 20'ye kadar olan varlıkları dağıtmanın 5448 yolu vardır. Yalnızca birkaç satır görüntülenir.

Biçim

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,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


Önceden gönderilen düzenlemeler düzenlemeler arasında bulunabilir. Olduğu gibi çok daha verimsiz Permutations.


Mathematica böyle bir görev için güzel görünüyor. Son bir şey, gerçek eşlerin muhtemelen en değerli 5 öğenin hepsi bir yığın halinde olduğu tartışmalıdır. (Evet, 1'den 20'ye kadar argümanlara yer kalmadan çözüm yok)
TheConstructor

@Geçerli olarak, varlıkları dağıtmanın birkaç yolu vardır. Zeyilnamede bazı yolları listeledim. Not: Sadece bir eşin malları listelenmiştir; diğeri tamamlayıcıyı alır.
DavidC

Inital yığınlarımı benim gibi inşa etmeyi tercih etmemin nedenlerinden biri de bu: Normalde en değerli iki şey aynı yığın üzerinde değil. İlk çözümünüz, toplamda 21 olmak üzere 10 çift sayı olduğunu kanıtlamaktadır; ardışık çiftleri dolaylı olarak seçersiniz.
Yapıcı

Evet, yaklaşımınızın mantığını takdir ediyorum.
DavidC

2

J

Evde takip etmek istemeniz durumunda , bu bağlantıda tüm J ilkellerinin bir hile sayfası var . Unutmayın: J genellikle sağdan sola okunur, bu yüzden 3*2+19 değil, 7'dir. Her fiil (işlev için J) ya monadiktir, bu yüzden öndeki gibi f yya da ikili, yani arasında 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

Notlar ve açıklamalar:

  • u/"katla u" anlamına gelir , bu nedenle listedeki her öğe üzerinde ikili işlemi gerçekleştirin. Örneğin: Fold Plus veya Sum+/ anlamına gelir ; olduğu daha az , böylece araçlar daha az Katlama veya minimum .<.<./

  • u"1" u1 boyutlu hücreler üzerinde performans" anlamına gelir , yani her satırda. Normalde J'deki fiiller ya atomiktir ya da tüm argümana uygulanır. Bu fiil ikili olarak kullanılıyorsa her iki argüman için de geçerlidir (iki argümanla). Aşağıdakileri göz önünde bulundur:

       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
    
  • #:bir sayıyı ikili gösterimine genişleten bir fiildir. Birden fazla öğeye sahip bir listede kullandığınızda, tüm sayıları düzgün bir şekilde hizalar, böylece #:i.2^nher ikili uzunluk dizesini elde edersiniz n.

  • /., ikili olarak kullanıldığında Key olarak adlandırılır . Sol taraftaki listenin öğelerini anahtar, sağ taraftaki öğeleri değer olarak kullanır. Bir anahtarı paylaşan her bir değer kümesini gruplandırır ve daha sonra bunlar üzerinde bazı işlemler gerçekleştirir.

    ]/.Operasyon durumunda , sadece kimlik fiilidir, bu yüzden orada tamamen özel bir şey olmuyor, ancak /.listeyi bizim için ayıracak olan şey önemli. Bu yüzden ikili listeleri yaratırız: böylece her liste ( "1) için eşlerin armağanlarını mümkün olan her şekilde bölebiliriz.

  • 1!:1]1ve 1!:2&2sırasıyla okuma ve yazma işlemleri. 1!:nBölüm fiil, diğeri sayı dosya tanıtıcısı olduğunu. 1içinde konsol olduğunu 2dışarı teselli olduğunu ve 3 4 5stdin, stdout ve stderr vardır. Ayrıca "., giriş dizelerini sayılara dönüştürmek için okurken de kullanırız .


1
Anlaşılabilir olması için J ve AT EN AZ DENGEDEKİ bir cevap göndermek için +1.
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)))))

Ölçek

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


 =: [89 -4 1 2]
    [36 20 7 5]
    Diff 20

Sonuç kümeleri eşit boyutta olmalı ve her kümenin içindeki değerler arasındaki fark yazdırılmalıdır. İdeone üzerinde hızlı bir testin sonuçlarına bakılırsa, her iki noktayı da kaçırmış olabilirsiniz
TheConstructor

sonucu yazdırmak için görüntüleme yöntemi ekleyin.
Mamun

Sonuç şimdi eşit boyuta ayarlandı
Mamun

Programınız [1 4 5 6 7 8]için [8 5 4] [7 6 1] Diff 31 fark ile net çözümlerin olduğu yerlerde hesaplanır .
Yapımcı

1

MATLAB

İşte benim çözümüm:

%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)

Örneğin, kaynak kodumdaki mevcut liste şu şekilde sonuçlanır:

for_jennifer =

     8     2     5     1


for_kate =

     4     7     2     3

ikisi de 16.

Eğer daha az eğlenceli kodumu golf, ben çok optimize edilmemiş 132 karakter olsun. Bunun üstesinden gel ;)

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{:}

Giriş dizisi kare olmalıdır.
DavidC

Hayır, kare değil mi? Ama şimdi görüyorum ki öğe sayısı ilk sırada olmalı. Ben değiştireceğim.
mmumboss

0

PHP

Uyarı: Çok kirli kod
Giriş dizisinin olası her permütasyonunu dener.

Ideone örneği 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!');

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]

veya biraz golfize:

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]

Ya da daha da golfize, çünkü çizgilerin yarısı sadece makyaj. (op içinde belirtilmediği için sadece ham dahili diziyi dökebileceğimi varsayarak print) Etkileşimli kabuğun içinde (örneğin) bırakabilir ve gerçekten isterseniz bir [::-1](en sonunda, sonra [0]) ekleyebilirsiniz. fark en son.

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]

(sonuç (0, ((1, 2, 7, 8), (3, 4, 5, 6))))

Bununla birlikte, bu sadece tüm olası kombinasyonları kaba kuvvetlendirir ve uzaktan verimli olarak değerlendirilmemelidir. Ancak, listenin eşit uzunluklarda olması önemli değilse, bu da işe yarayacaktır (büyük dizilerde):

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))

Örneğin bunun altındaki kodla, neredeyse hiç farkla çalışır: 10 ^ 10 maksimum değerinde 500k çok fazla değildir. Bu da çok daha hızlıdır: diğer kod muhtemelen bir yılın altında bitmeyecekse (ve bu çok iyimser), milajınız değişse bile, yaklaşık yarım saniye içinde çalışır.

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))

Soru: Bu neden bir CW postası?
HyperNeutrino

0

Okuryazar Haskell

> import Data.List
> import Data.Function

Liste monad'ını bölmek için kullandım.

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

Sonra bir derecelendirme yaparız.

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

Ve sonra farkı en aza indirecek bir işlev.

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

Ve hepsini birleştiren bir şey.

> bestDivison=best . divide

Sonraki ayrıştırıcı.

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

Ve bir çıktı formatlayıcı.

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

Ve şimdi program

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

Misal:

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

5 36 20 7
1 89 2 -4
diff=20

Sonuç kümeleri eşit boyutta olmalıdır
TheConstructor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.