33-dars: Bit va bitmask
5-darajaOlimpiada — musobaqa mahorati33–40 darslar
Bu darsdan keyin siz
- to’plamni son sifatida ifodalaysiz va uning bitlarini o’qiysiz
- barcha
2ⁿichki to’plamni bitta sikl bilan aylanasiz - holatlarni to’plam bilan belgilaydigan DP yozasiz
Avval qo’lda
“Avval qo’lda” bo'limiga havolaAvval qo‘lda
To’rtta tangani qatorga tering. Har tanga yozuv tomoni bilan tursa — 1, teskari bo’lsa — 0. Hozirgi holatni ikkilik son sifatida o’qing va uning o’nlik qiymatini yozing.
Endi barcha holatlarni tartib bilan chiqing: 0000, 0001, 0010…
Nechtasi bor va oxirgisi qaysi son?
Nimani sezishingiz kerak
16 ta holat, oxirgisi 15. Ya’ni 0 dan 2⁴ − 1 gacha bo’lgan har
son bitta holatni ifodalaydi. Endi «barcha variantni ko’rish»
oddiy for siklga aylandi.
Kompyuter yopiq. Bu mashq tugamaguncha kod ochilmaydi.
Bitlar bilan ishlash
“Bitlar bilan ishlash” bo'limiga havolaKerakli amallar oz va ular Computer Fundamentals modulida ko’rilgan. Bu yerda ularning to’plam sifatidagi ma’nosi muhim.
| Amal | Ma’nosi |
|---|---|
1 << i |
faqat i-bit yoqilgan son |
m | (1 << i) |
to’plamga i ni qo’shish |
(m >> i) & 1 |
i to’plamda bormi |
m & (m - 1) |
eng past yoqilgan bitni o’chirish |
m & (-m) |
faqat eng past yoqilgan bit |
Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
maska = 0maska |= 1 << 2maska |= 1 << 0print(bin(maska), maska)print((maska >> 2) & 1, (maska >> 1) & 1)print(bin(maska | (1 << 1)))Haqiqiy natija:
0b101 5 1 0 0b111
To'plam {0, 2} bitta son bilan — 5 bilan — ifodalandi. Element qo'shish, tekshirish va olib tashlash bitta amalda bajariladi.
Javobni ko'rish
0b101 5 1 0 0b111
To'plam {0, 2} bitta son bilan — 5 bilan — ifodalandi. Element qo'shish, tekshirish va olib tashlash bitta amalda bajariladi.
Barcha ichki to’plamlar
“Barcha ichki to’plamlar” bo'limiga havolabitmaskbitmask
Ichki to’plamni butun son bilan ifodalash usuli: sonning i-biti
i-element to’plamda bor-yo’qligini bildiradi.
sonlar = [3, 1, 4, 2]n = len(sonlar)eng = 0for maska in range(1 << n): y = sum(sonlar[i] for i in range(n) if (maska >> i) & 1) if y <= 6 and y > eng: eng = yprint(eng)Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
sonlar = [3, 1, 4, 2]n = len(sonlar)eng = 0for maska in range(1 << n): y = sum(sonlar[i] for i in range(n) if (maska >> i) & 1) if y <= 6 and y > eng: eng = yprint(eng)Haqiqiy natija:
6
Yig'indisi 6 dan oshmaydigan eng katta to'plam — masalan 3 + 1 + 2 yoki 4 + 2. Barcha 16 variant bitta sikl bilan ko'rib chiqildi.
Javobni ko'rish
6
Yig'indisi 6 dan oshmaydigan eng katta to'plam — masalan 3 + 1 + 2 yoki 4 + 2. Barcha 16 variant bitta sikl bilan ko'rib chiqildi.
Sig‘adimi?
Bir soniyada taxminan 10⁸ oddiy amal bajariladi.
| Yechim | n = 20 | n = 25 | n = 40 |
|---|---|---|---|
Barcha ichki to‘plamlar2^n | 10⁶sig‘adi | 10⁷sig‘adi | 10¹²sig‘maydi |
Holatlar bo‘yicha DP (2^k, k = 10)1 | 1sig‘adi | 1sig‘adi | 1sig‘adi |
Yashil — yechim o‘tadi. Sariq — chegarada, konstanta va til muhim bo‘lib qoladi. Qizil — bu yechim bilan bormaydi, boshqasini qidiring.
n ≤ 20 chegarasi deyarli har doim shu usulga ochiq taklif. n = 40
bo’lsa esa boshqa narsa kerak.
Bitmask ustida DP
“Bitmask ustida DP” bo'limiga havolaEndi kuchliroq g’oya. Masala: k xil ko’nikma kerak, n nomzod bor,
har biri ba’zi ko’nikmalarni biladi. Eng kichik jamoa nechta kishidan
iborat?
To’liq izlash 2ⁿ jamoani ko’radi. Lekin erishilgan ko’nikma
to’plamlari 2ᵏ ta — va odatda k ancha kichik.
nomzod = [0b011, 0b110, 0b001, 0b100]k = 3toliq = (1 << k) - 1CHEKSIZ = 99dp = [CHEKSIZ] * (toliq + 1)dp[0] = 0for m in range(toliq + 1): if dp[m] == CHEKSIZ: continue for maska in nomzod: yangi = m | maska if dp[m] + 1 < dp[yangi]: dp[yangi] = dp[m] + 1print(dp[toliq])Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
nomzod = [0b011, 0b110, 0b001, 0b100]k = 3toliq = (1 << k) - 1CHEKSIZ = 99dp = [CHEKSIZ] * (toliq + 1)dp[0] = 0for m in range(toliq + 1): if dp[m] == CHEKSIZ: continue for maska in nomzod: yangi = m | maska if dp[m] + 1 < dp[yangi]: dp[yangi] = dp[m] + 1print(dp[toliq])Haqiqiy natija:
2
Birinchi va ikkinchi nomzod birga uchala ko'nikmani qoplaydi. Holatlar soni 8 ta — nomzodlar soni 30 bo'lganda ham shuncha qoladi.
Javobni ko'rish
2
Birinchi va ikkinchi nomzod birga uchala ko'nikmani qoplaydi. Holatlar soni 8 ta — nomzodlar soni 30 bo'lganda ham shuncha qoladi.
Foydali hiylalar
“Foydali hiylalar” bo'limiga havolaAvval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
x = 12print(bin(x), x & (-x), x & (x - 1), bin(x >> 1))print(bin(x).count("1"), x.bit_count())Haqiqiy natija:
0b1100 4 8 0b110 2 2
x & (-x) — eng past yoqilgan bit (Fenwick daraxti shunga qurilgan, 32-dars). x & (x-1) uni o'chiradi. bit_count() yoqilgan bitlar sonini beradi.
Javobni ko'rish
0b1100 4 8 0b110 2 2
x & (-x) — eng past yoqilgan bit (Fenwick daraxti shunga qurilgan, 32-dars). x & (x-1) uni o'chiradi. bit_count() yoqilgan bitlar sonini beradi.
Sinab ko’r
“Sinab ko’r” bo'limiga havolaVizualda to’rtta sonning barcha 16 ta ichki to’plami ko’rib chiqiladi. Yuqori qator — maskaning bitlari.
Bitmask — barcha ichki to'plamlar
Yuqori qator — maskaning bitlari. Har bit bitta sonning taqdirini hal qiladi.
0 dan 2 darajali n gacha bo'lgan har son bitta ichki to'plamni ifodalaydi: uning bitlari qaysi elementlar olinganini ko'rsatadi.
Algoritmning har qadami quyidagi ro‘yxatda matn sifatida ham berilgan — vizual faqat shu qadamlarni chizadi, yangi ma’lumot qo‘shmaydi.
- To'rtta son bor va yig'indisi 6 dan oshmaydigan eng katta to'plam kerak. Har son uchun ikki variant — olish yoki olmaslik, demak 2 darajali 4 = 16 to'plam.
- Maska 0001: yig'indi 3 — sig'adi va yangi eng yaxshi natija.
- Maska 0011: yig'indi 4 — sig'adi va yangi eng yaxshi natija.
- Maska 0101: yig'indi 7 — 6 dan oshdi, bu to'plam yaramaydi.
- Maska 0110: yig'indi 5 — sig'adi va yangi eng yaxshi natija.
- Maska 0111: yig'indi 8 — 6 dan oshdi, bu to'plam yaramaydi.
- Maska 1011: yig'indi 6 — sig'adi va yangi eng yaxshi natija.
- Maska 1101: yig'indi 9 — 6 dan oshdi, bu to'plam yaramaydi.
- Maska 1110: yig'indi 7 — 6 dan oshdi, bu to'plam yaramaydi.
- Maska 1111: yig'indi 10 — 6 dan oshdi, bu to'plam yaramaydi.
- Eng yaxshi natija — 6. Har to'plam bitta SON bilan ifodalandi: maskaning i-biti «i-son olindimi» degan savolga javob beradi.
To'rtta son bor va yig'indisi 6 dan oshmaydigan eng katta to'plam kerak. Har son uchun ikki variant — olish yoki olmaslik, demak 2 darajali 4 = 16 to'plam.
Ko'rilgan to'plam0
Xatoni toping
“Xatoni toping” bo'limiga havolaTuzoq — xatoni toping
33 / 40
Masalan ta sonning barcha ichki to'plamlarini ko'rib chiqing.
Taklif qilingan yechim
Bu javobning 2-qismi noto'g'ri. maska & i — bu i-bitni emas, i SONINING bitlarini tekshiradi. To'g'ri shakl: maska & (1 << i) yoki (maska >> i) & 1. Yozilgani i = 0 da har doim nol beradi va i = 3 da ikkita bitni birdan qamraydi.
Javobning qaysi qismi noto'g'ri? Bosib belgilang.
maska & i — bu i-bitni emas, i SONINING bitlarini tekshiradi. To'g'ri shakl: maska & (1 << i) yoki (maska >> i) & 1. Yozilgani i = 0 da har doim nol beradi va i = 3 da ikkita bitni birdan qamraydi.
Xato hech qanday xabar bermaydi: kod ishlaydi va javob beradi — shunchaki boshqa to’plamlarni ko’radi. Kichik misolda barcha maskalarni chop etib tekshirish eng tez yo’l.
O’zingizni sinang
“O’zingizni sinang” bo'limiga havola1n elementli to'plamning nechta ichki to'plami bor?
Javobni ko'rish
2ⁿ. Har element uchun ikki variant — bor yoki yo’q.
2To'plamga i elementini qanday qo'shasiz?
Javobni ko'rish
m |= 1 << i. Bor-yo’qligini esa (m >> i) & 1 bilan tekshirasiz.
3n ≤ 20 chegarasi nimani ishora qiladi?
Javobni ko'rish
2ⁿ yechimni: 2²⁰ taxminan bir million, bu bemalol sig’adi.
Shunchalik kichik chegara deyarli har doim ochiq taklif.
4Bitmask DP da nima sanaladi?
Javobni ko'rish
Tanlovlar emas, erishilgan to’plamlar. Ular 2ᵏ ta, k esa
odatda elementlar sonidan ancha kichik.
5x & (-x) nima beradi va u qayerda ishlatilgan?
Javobni ko'rish
Eng past yoqilgan bitni. Fenwick daraxti (32-dars) butunlay shu amalga qurilgan.
Masalalar
“Masalalar” bo'limiga havolaMasalalar
3 ta
- Apple DivisionCSES 1623o'rta
n ≤ 20. Har olma ikki guruhdan birida — bu aynan bitmask.
- Hamiltonian FlightsCSES 1690qiyin
Holat: (ko‘rilgan shaharlar to‘plami, hozir qayerdaman). Klassik bitmask DP.
- Elevator RidesCSES 1653qiyin
Har holat uchun ikki qiymat saqlanadi: liftlar soni va oxirgi liftdagi og‘irlik.
Lokal mashq: mashqlar/33-jamoa/ — masala matni, testlar va tekshir.py. Avval sekin.py ni o‘zingiz yozing, keyin tayyorini oching.
Topshiriq
“Topshiriq” bo'limiga havolaTopshiriq — darajangizni tanlang
Asos · 5–7-sinf — Vizual va aniq ko'rsatmali
To’rtta tangaga qaytib, 16 ta holatni ikkilik va o’nlik ko’rinishda jadvalga yozing. Keyin har holat uchun yoqilgan bitlar sonini yozing — qaysi sonlarda u eng katta?
Mustahkam · 8–9-sinf — Matnli masala, o'zingiz tuzasiz
33-jamoa masalasini yeching. sekin.py (2ⁿ) va tez.py (2ᵏ)
vaqtini n = 16, k = 10 da solishtiring.
Chuqur · 10–11-sinf — Algoritmik, chegara holatlari bilan
Berilgan maskaning barcha ichki to’plamlarini aylanadigan sikl
yozing. Ishora: q = (q - 1) & maska. Nega bu barcha ichki
to’plamni beradi va nechta qadam qiladi?
Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.