Tugas
Anda akan diberi satu set lingkaran di pesawat dengan pusatnya di garis y = 0 . Dijamin tidak ada pasangan lingkaran yang memiliki lebih dari satu titik umum.
Tugas Anda adalah menentukan berapa banyak wilayah di mana lingkaran membagi bidang. Wilayah adalah kumpulan titik berdekatan inklusi-maksimal yang tidak memotong lingkaran apa pun.
Anda harus menulis sebuah program yang menghitung jawaban ini ketika diberi deskripsi lingkaran.
Ini sebuah contoh:
Di sisi kiri Anda melihat lingkaran yang tergambar di pesawat. Namun, di bagian kanan gambar, wilayah yang diproduksi oleh lingkaran diwarnai dengan jelas (satu warna per wilayah). Ada enam wilayah dalam contoh ini.
Memasukkan
Baris pertama dari input berisi angka,, N
jumlah deskripsi lingkaran untuk diikuti. Baris ini bersifat opsional, jika solusi Anda berfungsi tanpanya, tidak masalah.
Baris berikut N
masing-masing berisi dua bilangan bulat, x i dan r i > 0 , mewakili lingkaran dengan pusat (x i , 0) dan jari-jari r i .
Dijamin tidak ada pasangan lingkaran yang memiliki lebih dari satu titik umum. Lebih lanjut dijamin bahwa x i dan r i tidak melebihi 10^9
nilai absolut (sehingga mereka cocok dengan integer 32-bit).
Inputnya mungkin:
baca dari STDIN
baca dari file yang bernama
I
di direktori saat ini
Atau, inputnya bisa:
tersedia sebagai string (termasuk baris baru) dalam variabel global
di tumpukan
Keluaran
Ini harus berupa bilangan bulat tunggal, jumlah ke daerah yang diproduksi. Ini harus ditulis ke STDOUT atau file bernama O
di direktori saat ini.
Aturan
Kode terpendek dalam byte menang
+200 byte penalti jika kode Anda tidak memiliki runtime + kompleksitas ruang polinomial masuk
n
-100 byte bonus untuk runtime + kompleksitas ruang terburuk yang diharapkan
O(n log n)
-50 byte bonus untuk runtime + kompleksitas ruang terburuk yang diharapkan
O(n)
Bonus -100 byte untuk runtime deterministik + kompleksitas ruang
O(n)
Saat menilai runtime:
Asumsikan bahwa tabel hash
O(1)
mengharapkan runtime untuk memasukkan, menghapus, dan mencari, terlepas dari urutan operasi dan data input. Ini mungkin benar atau tidak benar, tergantung pada apakah penerapannya menggunakan pengacakan.Asumsikan bahwa jenis bahasa pemrograman bawaan Anda membutuhkan
O(n log n)
waktu deterministik , di manan
ukuran urutan input.Asumsikan bahwa operasi aritmatika pada nomor input hanya memakan
O(1)
waktu.Jangan berasumsi bahwa angka-angka input terikat oleh konstanta, meskipun, karena alasan praktis, mereka. Ini berarti bahwa algoritma seperti jenis radix atau jenis penghitungan bukanlah waktu linier. Secara umum, faktor konstan yang sangat besar harus dihindari.
Contohnya
Memasukkan:
2
1 3
5 1
Keluaran: 3
Memasukkan:
3
2 2
1 1
3 1
Keluaran: 5
4
7 5
-9 11
11 9
0 20
Memasukkan:
9
38 14
-60 40
73 19
0 100
98 2
-15 5
39 15
-38 62
94 2
Keluaran: 11
Petunjuk
Kita dapat menggunakan ide berikut untuk solusi yang sangat ringkas. Mari kita memotong set lingkaran dengan sumbu X dan menafsirkan titik-titik persimpangan sebagai node dalam grafik planar:
Setiap lingkaran menghasilkan tepat 2 tepi dalam grafik ini dan hingga dua node. Kita dapat menghitung jumlah node dengan menggunakan tabel hash untuk melacak jumlah total batas kiri atau kanan yang berbeda.
Kemudian kita bisa menggunakan rumus karakteristik Euler untuk menghitung jumlah wajah dari gambar grafik:
V - E + F - C = 1
F = E - V + C + 1
Untuk menghitung C
, jumlah komponen yang terhubung, kita bisa menggunakan pencarian kedalaman-pertama .
Catatan: Gagasan masalah ini dipinjam dari kontes pemrograman Kroasia baru - baru ini , tapi tolong jangan menipu dengan melihat garis besar solusinya. :)
n log n
bonus? Juga, saya punya solusi baru secara konseptual baru. Haruskah saya mengirim jawaban baru untuk menggantikan yang lama? (Saya lebih suka yang pertama, kalau-kalau solusi baru saya tidak benar-benar benar)Jawaban:
Mathematica,
125122 - 150 = -28 karakterSaya tidak tahu kerumitan fungsi bawaan
ConnectedComponents
.Pemakaian:
sumber
ConnectedComponents
linier memiliki kompleksitas terburuk, jadi jika ada komponen O (n), ini akan baik-baik saja. Saya tidak mengerti Mathematica, jadi saya tidak tahu apakah itu O (n) secara keseluruhan dan memenuhi syarat untuk bonus -150? Saya kira begitu. Apakah saya hanya menjalankannya dengan input di STDIN?Ruby -
312306285273269259 karakterJawaban ini telah digantikan oleh pendekatan saya yang lain yang menggunakan karakter jauh lebih sedikit dan berjalan di
O(n log n)
.Oke, ayo pergi. Sebagai permulaan, saya hanya ingin implementasi yang berhasil, jadi ini belum dioptimalkan secara algoritmik. Saya mengurutkan lingkaran dari yang terbesar ke yang terkecil, dan membangun pohon (lingkaran yang termasuk dalam lingkaran lain adalah anak-anak dari yang lebih besar). Kedua operasi mengambil yang
O(n^2)
terburuk danO(n log n)
terbaik. Kemudian saya beralih melalui pohon untuk menghitung area. Jika anak-anak lingkaran mengisi seluruh diameternya, ada dua area baru, jika tidak hanya ada satu. Pengulangan ini dilakukanO(n)
. Jadi saya memiliki kompleksitas keseluruhanO(n^2)
dan memenuhi syarat untuk hadiah maupun penalti.Kode ini mengharapkan input tanpa jumlah lingkaran untuk disimpan dalam variabel
s
:Versi tidak dikumpulkan (mengharapkan input dalam variabel
string
):sumber
11
. Untuk yang ada di komentar Anda9
.10
dan8
dengan versi saya yang tidak disunat, tetapi11
dan9
dengan versi golf saya saat ini: DRuby,
203183173133 - 100 = 33 karakterJadi inilah pendekatan yang berbeda. Kali ini, saya mengurutkan lingkaran berdasarkan titik paling kiri mereka. Lingkaran yang menyentuh pada titik paling kiri diurutkan dari yang terbesar hingga yang terkecil. Ini membutuhkan
O(n log n)
(well, Ruby menggunakan pengurutan cepat, jadi sebenarnyaO(n^2)
tetapi menerapkan pengurutan gabungan / heap mungkin di luar cakupan tantangan ini). Kemudian saya beralih ke daftar ini, mengingat semua posisi paling kiri dan paling kanan dari lingkaran yang telah saya kunjungi. Ini memungkinkan saya mendeteksi jika serangkaian lingkaran menghubungkan semua jalan melintasi lingkaran yang lebih besar. Dalam hal ini, ada dua subarea, atau hanya satu. Iterasi ini hanyaO(n)
memberikan kompleksitas totalO(n log n)
yang memenuhi syarat untuk hadiah 100 karakter.Cuplikan ini mengharapkan input akan diberikan melalui file dalam argumen baris perintah tanpa jumlah lingkaran:
Versi tidak dikumpulkan (mengharapkan input dalam variabel
string
):sumber
-1 1 1 1 0 2 4 2 0 6
. Saya akan memikirkan cara memperbaikinya besok malam (semoga).Julia - 260 -100 (bonus?) = 160
UPDATE: Dengan berpikir sebentar saya menemukan bahwa masalah dengan metode saya hanya ketika lingkaran di mana tidak terhubung, jadi saya datang dengan sebuah ide, mengapa tidak menghubungkan mereka secara artifisial? Jadi keseluruhan akan memenuhi formula Euler.
F = 2 + EV (V = 6, E = 9)
[Jangan bekerja dengan lingkaran bersarang, jadi itu bukan jawaban masalah untuk kasus umum]
Kode :
sumber
2 -10 1 10 1
.n=2
, lingkarannya adalah(C=(-10,0), r=1)
dan(C=(10,0), r=1)
4 0 2 1 1 10 2 11 1
Tapi saya rasa saya tidak bisa memberi Anda lebih banyak test case, itu akan sedikit tidak adilSpidermonkey JS,
308, 287, 273 - 100 = 173Saya pikir jika saya menulis ulang ini dalam Ruby atau Python saya bisa menyimpan karakter.
Kode:
Algoritma:
Saya tidak terlalu hebat dalam notasi O besar, tapi saya pikir itu O (n) karena saya secara efektif perulangan melalui setiap lingkaran 3 kali (buat, kiri, kanan) dan juga menyortir kunci peta (dan saya mengurutkan untuk O ( n log n) tetapi itu menghilang). Apakah ini deterministik?
sumber
r
loop danl
loop menjadi satu pernyataan, saya akan sangat menghargainya.JavaScript (ES6) -
255254 Karakter -100250 Bonus =1554Mengasumsikan bahwa string input dalam variabel
S
dan menampilkan jumlah daerah ke konsol.Kompleksitas waktu sekarang O (N).
Test Case 1
Output:
3
Test Case 2
Output:
5
Test Case 3
Output:
6
Test Case 4
Output:
11
Test Case 5
Output:
105
Versi sebelumnya
Dengan komentar:
Kompleksitas waktu total adalah O (N) untuk segala sesuatu kecuali jenisnya yaitu O (N.log (N)) - namun dengan mengganti ini dengan jenis ember, ini akan mengurangi kompleksitas total menjadi O (N).
Memori yang diperlukan adalah O (N).
Coba tebak apa yang berikutnya pada daftar todo saya ... ember urutkan kurang dari 150 karakter.Selesaisumber
O(n)
(pada kenyataannyaO(n+k)
), tetapiO(n^2)
atauO(n log n)
kasus terburuk tergantung pada algoritma penyortiran yang digunakan dalam bucket, jadi Anda harus melakukannya dalam 50 karakter.