CJam, 68 61 84 ... 59 49 48 79 byte
l~]__,+:+M@{:Ze<:X2/)_2*X-@+@@-\Z}*;[YY]/_,(\R*_,,:)W%{2\2*1a*+2+/_S*\,(@+\}/;+
Mengambil input dalam format yang sama seperti pada pertanyaan.
PEMBARUAN : Memperbaiki algoritme untuk kasus uji yang serupa dengan yang ditunjukkan oleh @nutki. Meskipun itu membuat kode hampir dua kali lipat, akan mencoba untuk golf sekarang setelah diperbaiki.
Cara kerjanya (Agak tidak lengkap, akan menambahkan 2 1 2penjelasan paritas nanti)
Segera setelah saya melihat pertanyaan ini, saya tahu bahwa akan ada rumus matematika untuk mendapatkan jawabannya. Setelah mencoba beberapa kombinasi, saya pikir rumusnya adalah2 * Number of blocks - Number of shared streets
Mari kita periksa untuk 2 1kasus:
2 * 3 - 2 = 4
Benar.
Mari kita periksa 3 1 2 4kasusnya:
2 * 10 - 10
Perbaiki lagi. Yipee, begitu kodenya
l~]:L:+2*L:(:+L(+-[{_@e<}*]:+-
Sekarang mari kita coba ini pada beberapa contoh lagi:
3 3
Keluaran:
2 * 6 - 7 = 5
Tapi tunggu, jawaban yang sebenarnya adalah 6
Mari kita coba yang lain:
5 5
2 * 10 - 13 = 7 // Answer is 9 instead.
Anda melihat polanya?
Untuk setiap N Npasangan blok, di mana N adalah bilangan bulat positif lebih besar dari 2, saya memerlukan float((N+1)/2)-1cop tambahan selain rumus di atas. Mari kita verifikasi lagi:
5 5 3
2 * 13 - 18 = 8 // Answer is 11
Dalam contoh di atas, kami memiliki 1 5 5pasangan dan 1 3 3pasangan (dari 5 3blok)
Mari kita coba contoh lain
5 5 4 4
2 * 18 - 27 = 9 // Answer is actually 14
Anda harus berpikir bahwa hanya ada 5 5, 3 3dan 3 3berpasangan (dari blok 5 5, 5 4dan 4 4resp.), Sehingga hanya 4 polisi tambahan yang diperlukan, tetapi ada satu pasangan lagi.
Dari blok 4 4, kami hanya menggunakan 3 3sehingga kami memiliki 1 1gratis, ini membuat 3 3pasangan blok lain yang dapat divisualisasikan menggunakan gambar di bawah ini:

Garis merah adalah pasangan yang biasa, garis biru adalah pasangan tegak lurus yang saya bicarakan di atas.
Agak sulit dijelaskan karena sementara garis merah hanya berbagi 1 sisi pasangan, sisi biru juga berbagi 1 sisi + 1 blok. Tetapi logika ini berfungsi untuk semua kombinasi blok.
Kode sekarang hanya menghitung itu.
l~]__ "Read the input numbers, convert to array and make two copies";
,+ "Get the number of columns and add that to the block array";
:+ "Sum the array elements to get number of blocks + columns";
M@ "Push empty array to stack and rotate input array to top";
{ }* "Run this block for each pair in the block array";
:Ze<:X "Store the later block size in Z, and minimum of two in X";
@\- "Rotate swap and subtract shared sides from total sum";
X)Y/(:T+ "Increment halve and decrement. Store in T and add to sum";
XTY*- "Find unused blocks from this pair for perpendicular pairs";
@+ "Add unused blocks to the array M";
Z "Push Z to stack to be used in next iteration";
;[YY] "Pop the last pushed Z and push array [2 2] to stack";
/,(+ "Check how many perpendicular pairs exist, add to total sum";
Catatan yang 2 * Number of blocks - Number of shared sidesjuga bisa ditulis sebagai
Number of blocks + Number of columns - Number of shared sides between adjacant columns
Cobalah online di sini