لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=245
نوع سوال: نظریه ی گراف
توضیح راه حل :
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=246
نوع سوال: نظریه ی اعداد
توضیح راه حل : می توان مساله را به این صورت مطرح کرد که “بیشترین تعداد مهره های سیاهی که می توانیم در حلقه قرار دهیم بدون اینکه فاصله ی هیچ کدام از دو تای آنها N شود چیست؟”. اگر این سوال را پاسخ این سوال را پیدا کنیم، پاسخ سوال اصلی یکی بیشتر از این مقدار خواهد بود.
اگر مهره ی i-ام را به مهره ی
وصل کنيم، گرافی بدست می آوریم که در آن نمی توانیم دو راس مجاور را سیاه رنگ کنیم. اگر دقت کنیم، این گراف متشکل از یک یا چند حلقه است، زیرا درجه ی هر راس برابر با 2 است. ماکزیمم تعداد راس هایی که در یک حلقه با
راس می توانیم سیاه رنگ کنیم، برابر با
است. تعداد حلقه ها نیز برابر با
است و طول هر حلقه برابر
است. بنابراین جواب سوال برابر خواهد شد با:
.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=247
نوع سوال: ریاضی + برنامه سازی پویا + اعداد صحیح با دقت بالا
توضیح راه حل : اگر راه حل بدیهی
را پیاده سازی کنید و مقادیر مربوط به جدول برنامه سازی پویا را نگاه کنید، می توان جواب را به راحتی حدس زد (با توجه به این مجموع عناصر سطر آخر جدول برنامه سازی پویا باید برابر با
باشد و عنصر اول 2 تا بیشتر از بقیه ی عناصر دیگر است و سایر عناصر برابر هستند):
.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=248
نوع سوال: نظریه ی اعداد + برنامه سازی پویا
توضیح راه حل : می توان از برنامه سازی پویا مانند مساله Knapsack استفاده کرد و مساله را به راحتی با پیچیدگی زمانی
حل کرد. راه حلی که از قضایای نظریه ی اعداد استفاده کند نیز وجود دارد، ولی نوشتن کد روش برنامه سازی پویا بسیار آسان تر و کم تر است.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=249
نوع سوال: برنامه سازی پویا + تکرار ساده
توضیح راه حل: برای ساختن جواب، ابتدا کدهای گری حداکثر 19 بیتی را حساب می کنیم. کد های گری دنباله اعدادی هستند که دو عدد پشت سر هم تنها در یک بیت اختلاف دارند و کدهای گری
ام نیز با با صفر تنها در یک بیت اختلاف دارند.
برای ساختن کد گری
-ام،
را در مبنای دو می نویسیم، و رقم
-ام کد گری برابر خواهد بود با حاصل xor بیت های
و
-ام. البته اگر بخواهید کدهای گری را بیت به بیت درست کنید، زمان اجرای راه حل شما زِیاد خواهد شد. ولی با توجه به اینکه کد گری
-ام و
-ام تنها در یک بیت تفاوت دارند، می توانید از برنامه سازی پویا استفاده کنید.
پس از پیدا کردن کدهای گری، ساختن جدول دو بعدی که دو سلول مجاور تنها در یک بیت اختلاف دارند، کار سختی نیست. اگر جدولمان دارای n سطر و m ستون باشد، اگر سلول
را برابر با
قرار دهيم، هدفمان برآورده می شود.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=251
نوع سوال: هندسی
توضیح راه حل : برای n های بزرگتر از 4 جوابی وجود ندارد. برای n = 3 راه حل بدیهی است، و برای n = 4 با در نظر گرفتن چند حالت خاص می توان جواب را پیدا کرد.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=252
نوع سوال: نظریه ی گراف + تخصیص بهینه
توضیح راه حل: اگر تنها بخواهیم تعداد مسیرها را کمینه کنیم، با توجه به اینکه گراف بدون دور است، اگر تعداد رئوسی که parent دارند را بیشینه کنیم، تعداد مسیرها (که برابر با تعداد راس های بدون parent است) کمینه خواهد شد. این کار را می توان با استفاده از maximum bipartite matching انجام داد که در یک طرف گرف شهر ها به عنوان parent و در طرف دیگر به عنوان child قرار دارند.
حال اگر بخواهیم هزینه ی یال های انتخاب شده را نیز کمینه کنیم، می توانیم با استفاده از روش بالا و hungarian algorithm، جواب را در گرافی دو بخشی که وزن یال ها به جای عدد صحیح دوتایی مرتب است، بدست بیاوریم.
البته، راه حل دیگری نیز وجود دارد که آن را امتحان نکرده ام: با توجه به اینکه تطبیق بیشینه در گراف دو بخشی را می توان به صورت مساله ی maximum flow مدل سازی کرد، و الگوریتم های خوبی برای حل مساله ی جریان بیشینه با کمترین هزینه داریم، می توان از این الگوریتم ها نیز استفاده کرد.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=253
نوع سوال: هندسه + جستجوی دودوئی
توضیح راه حل: نقطه ای داخل چند ضلعی محدب است که پائین بخش بالای چند ضلعی و بالای بخش پائین چند ضلعی باشد. پس کافی است ابتدا بخش بالا و پائین چندضلعی را جدا کنیم، و سپس برای چک کردن اینکه آیا نقطه ای داخل چند ضلعی است، با جستجوی دودوئی این دو شرط را در
چک کنیم. پس پیچیدگی زمانی الگوريتم این مساله عبارت خواهد بود از
.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=254
نوع سوال: شبیه سازی
توضیح راه حل: اگر به صورت مستقیم و بی هیچ کار اضافی عملیات را در یک آرایه شبیه سازی کنید، در بدترین حالت حدود 4 ثانیه طول خواهد کشید.
به این دلیل که حافظه ای که برای این سوال داریم محدود است، حذف شدن ها را به این صورت نگه می داریم که
اگر کوچک تر از صفر باشد یعنی حذف شده است و اگر بزرگتر باشد یعنی حذف نشده است.
ولی اگر بعد از تعدادی عملیات حذف کردن، آرایه را دوباره و با دور ریختن عناصر حذف شده بسازیم، الگوریتم به اندازه ی کافی سریع خواهد بود که Accepted شود. مثلا من بعد از هر 100000 عملیات حذف کردن، آرایه را دوباره از اول می سازم و در بدترین حالت 788 میلی ثانیه طول می کشد.
لینک سوال: http://acm.sgu.ru/problem.php?contest=0&problem=255
نوع سوال: ریاضی + جستجوی دودوئی
توضیح راه حل: اگر
را برای
های کوچک حساب کنید، به راحتی می توان حدس زد که
و
. با محاسبه ی این مقادیر و جستجوی دودوئی می توان فهمید که آیا مقدار ورودی جزو این دنباله اعداد هست یا نه.