pengantar
Anda sendirian di sebuah pulau. Sisa umat manusia sudah mati ( mungkin karena bug dalam kode user12345 ). Zombie Pirate Horde telah mencapai pulau Anda, dan mereka tidak ada habisnya. Saatnya untuk menendang pantat atau mengunyah permen karet, dan Anda semua keluar dari permen karet.
Masalah
Skenario kiamat kami dijelaskan oleh 2 bilangan bulat pada satu baris, m
dan n
. Di pulau Anda ada pos-pos unik yang diberi nomor mulai dari 1 hingga m
. Berikut ini n
garis masing-masing berisi tiga bilangan bulat, x
, y
, dan z
, dipisahkan oleh spasi. x
dan y
merupakan ID unik dari dua pos terdepan, dan z
merupakan jumlah zombie yang akan ditemui di jalur di antara mereka.
Ketika Anda menempuh jalan, Anda kehilangan z
amunisi dan Anda membunuh z
zombie. Jika Anda menempuh jalan yang sama lagi, sayangnya, Anda akan menemukan jumlah zombie yang sama. Semua pos menghasilkan amunisi +1 setiap kali Anda menempuh jalur. Anda mulai dengan 100 amunisi di pos 1. Semua pos dimulai dengan 0 amunisi. Anda langsung mati jika tidak ada jalur yang amunisi Anda lebih besar dari jumlah zombie di jalur itu, dan sisa amunisi Anda dikonversi menjadi kill. Itulah pendirian terakhir Anda.
Tulis program yang menghasilkan jumlah zombie maksimum yang dapat Anda bunuh untuk skenario yang diberikan. Jika Anda dapat membunuh zombie dalam jumlah tak terbatas, cukup output x
.
Contoh Input
5 6
1 2 4
2 3 4
3 1 4
2 4 10
2 5 10
1 1 50
Contoh Output
x
Asumsi
- Jalur akan berada di antara dua pos yang valid. Artinya 1 <=
x
/y
<=m
- Jika jalur antara
x
dany
tidak terdaftar, itu tidak dapat dilalui - Jalan adalah dua arah
- 1
m
<<= 100 - 1
n
<<= 500 - Input harus diberikan melalui stdin, membaca dari file, atau diterima sebagai argumen tunggal untuk program, dan harus persis mengikuti format contoh
- Runtime dari program Anda mungkin besar sembarang tetapi harus terbatas
Kode dengan karakter paling sedikit menang!
1
mulai dengan 0 amunisi? Apakah grafiknya tidak langsung?1->1
membutuhkan amunisi 49, dan siklus itu1->2->3->1
memakan amunisi 3 dalam jangka panjang.Jawaban:
Jawa ( kurang aneh:
841552913301)Baik. Pada dasarnya, saya malu tidak ada yang mengajukan solusi. Jadi beberapa hari yang lalu saya mulai mencoba untuk menyelesaikan masalah ini, itu bagus. . Ikuti tautan itu untuk menyaksikan kemajuan saya di sana melalui GitHub.
Edit
Versi pemecah baru, lebih banyak "golf", dengan pemeriksa siklus yang diperbaiki sebagaimana diidentifikasi oleh MT0. Ini juga mendukung rute penerusan cepat, yang dapat disesuaikan dengan mengubah berapa banyak memori yang tersedia untuk VM. Sunting BIG terbaru : menyadari bahwa saya memiliki beberapa kesalahan indeks kecil dan optimasi prematur, yang mengakibatkan kegagalan untuk mempertimbangkan sejumlah besar jenis kemenangan. Jadi itu diperbaiki, hati-hati. Versi baru lebih kecil dan di bawah. Untuk rute referensi kami,
java -Xmx2GB ZombieHordeMin
lakukan triknya dengan cukup baik (diperingatkan, ini akan memakan waktu cukup lama).Factoid keren
Dalam twist yang menarik, ada solusi BANYAK panjangnya 24, dan pemecah saya menemukan satu berbeda dari MT0, tetapi pada prinsipnya identik, kecuali bahwa itu dimulai dengan mengunjungi pos-pos lain yang terhubung
1
. Menarik! Benar-benar melawan intuisi manusia, tetapi sangat valid.Sorotan Solusi
Jadi ini milikku. Ini (sebagian) golf, b / c itu pemecah eksponensial, hampir kasar. Saya menggunakan algoritma IDDFS (iterative deepening depth first search), jadi ini adalah pemecah umum yang hebat yang tidak melewatkan, sehingga memecahkan kedua bagian dari pertanyaan OP, yaitu:
Berikan kekuatan, ingatan, dan waktu yang cukup, dan itu akan melakukan hal itu, bahkan peta kematian lambat. Saya menghabiskan lebih banyak waktu untuk memperbaiki solver ini, dan sementara lebih banyak yang dapat dilakukan, itu sedikit lebih baik sekarang. Saya juga mengintegrasikan saran MT0 tentang solusi zombie tak terbatas terbaik, dan menghapus beberapa optimasi prematur dari win-checker saya yang mencegah versi sebelumnya menemukannya, dan sekarang saya sebenarnya menemukan solusi yang sangat mirip dengan yang dijelaskan oleh MT0.
Beberapa highlight lainnya:
Saya telah memasukkan algoritme untuk membuatnya lebih menarik untuk ditontonDihapus untuk tujuan bermain golf. Ikuti salah satu tautan ke github untuk melihat versi yang tidak diserang.Ada sejumlah komentar juga, jadi jangan ragu untuk menerapkan kembali untuk solusi Anda sendiri berdasarkan pendekatan saya, atau tunjukkan padaku bagaimana itu harus dilakukan!Sejarah pemecah masalah
Kode (golf)
Aktif ke kode (dapatkan versi yang tidak di -serigala di sini atau di sini ):
Dapatkan kode dari github di sini, untuk melacak setiap perubahan yang saya buat. Berikut adalah beberapa peta lain yang saya gunakan.
Contoh keluaran
Contoh output untuk solusi referensi:
Baca output rute seperti ini
step
::source
,route-to-get-here
-ammo
. Jadi dalam solusi di atas, Anda akan membacanya sebagai:0
, di pos terdepan1
dengan amunisi100
.1
, gunakan rute1
untuk mencapai pos3
dengan amunisi berakhir97
2
, gunakan rute1
untuk mencapai pos1
dengan amunisi berakhir95
Catatan penutup
Jadi, saya harap saya membuat solusi saya lebih sulit untuk dikalahkan, tapi TOLONG MENCOBA! Gunakan untuk melawan saya, tambahkan beberapa pemrosesan paralel, teori grafik yang lebih baik, dll. Beberapa hal yang saya pikir dapat meningkatkan pendekatan ini :
menyisihkan rute mati. Solusi saya saat ini tidak "ingat" bahwa rute tertentu buntu, dan harus menemukan kembali setiap waktu. Akan lebih baik untuk melacak momen paling awal dalam rute yang kematiannya pasti, dan tidak pernah maju setelahnya.melakukan ini ...Solusi lain yang memperdagangkan memori untuk waktu tertentu, atau memungkinkan penghindaran agresif mengikuti rute buntu.lakukan ini juga!sumber
Beberapa catatan abstrak tentang suatu solusi
Jika saya punya waktu, saya akan mengonversinya menjadi sebuah algoritma ...
Untuk grafik yang diberikan
G
maka ada sub-grafik terhubungG'
yang berisi kota1
. Jika ada solusi tak terbatas maka akan ada sub-graf terhubungG''
dariG'
yang berisiV
kota-kota danP
jalan.Jalur
P
dariG''
dapat dipartisi sehingga{p}
mengandung jalur yang memiliki biaya maka minimal semua jalan diP
danP/{p}
semua jalan lain (membentuk spanning tree atau mungkin siklus). Jika kita berasumsi bahwap
itu bukan perulangan (menghubungkan kedua ujungnya ke kota yang sama) maka itu akan menghubungkan dua kota (v1
danv2
) dan memilikic
amunisi biaya maka Anda (yang selamat) kemudian dapat melintasi dari danv1
kev2
belakang dengan total biaya2c
amunisi dan ini akan menambah amunisi di semua kota sebesar 2 (untuk peningkatan total di2|V|
dalamG''
- beberapa di antaranya akan dikumpulkan dariv1
danv2
).Jika Anda melakukan perjalanan dari
v1
untukv2
dan kembali kev1
beberapa (m
) kali dan kemudian melakukan perjalanan dariv1
sepanjang tepiP/{p}
untuk mengunjungi semua kota-kota selainv1
danv2
sebelum kembali kev1
dan ini membutuhkann
jalur untuk mencapai (di mana|P/{p}| ≤ n ≤ 2|P/{p}|
karena Anda tidak pernah harus perlu melintasi jalur yang lebih dari dua kali) dengan biayak
dan kota-kota akan mendapatkan2m|V|
amunisi (lagi beberapa di antaranya akan dikumpulkan selama perjalanan).Dengan semua ini maka Anda dapat mengetahui apakah solusi yang tak terbatas berpotensi terjadi jika biaya
k + 2mc
sama atau lebih rendah dari total hadiah2(m+n)|V|
.Ada kompleksitas tambahan untuk masalah ini yaitu:
1
ke{p}
pada iterasi pertama dan perlu memperhitungkan biaya ini; danm
dann
cukup rendah sehingga Anda tidak kehabisan amunisi sebelum Anda dapat membuatnya melalui iterasi pertama karena iterasi pertama akan memiliki biaya yang lebih tinggi daripada iterasi berikutnya).Ini mengarah ke solusi netral biaya 24 jalur untuk contoh dalam pertanyaan (jumlahnya adalah kota-kota yang dikunjungi):
sumber