چاپگر


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

یک مستطیل n×mn \times m را یک مستطیل ایکس-پُر می‌نامیم اگر تمام n.mn.m کاراکتر داخل این مستطیل X باشد. توجه کنید کاراکتر X بزرگ است!

یک مستطیل n×mn \times m را یک مستطیل نقطه-پُر می‌نامیم اگر تمام n.mn.m کاراکتر داخل این مستطیل . باشد.

امین از شما می‌خواهد یک مستطیل 3n×3m3n \times 3m را با ۹ مستطیل n×mn \times m پر کند.

او می‌خواهد این ۹ مستطیل به صورت شطرنجی(یکی در میان) ایکس-پُر و نقطه-پُر باشند و مستطیل بالا سمت چپ ایکس-پُر باشد. به عکس زیر توجه کنید: عکس سوال چاپگر

برای بهتر متوجه شدن خواسته‌ی امین، به مثال‌ها توجه کنید.

ورودی🔗

ورودی تنها شامل یک خط است که در آن دو عدد طبیعی nn و mm با فاصله از هم آمده است. 1n,m201 \le n, m \le 20

خروجی🔗

خروجی یک جدول 3n×3m3n \times 3m، مطابق با الگو خواسته شده، چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

1 1
Plain text

خروجی نمونه ۱🔗

X.X
.X.
X.X
Plain text

ورودی نمونه ۲🔗

2 3
Plain text

خروجی نمونه ۲🔗

XXX...XXX
XXX...XXX
...XXX...
...XXX...
XXX...XXX
XXX...XXX
Plain text

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

وضعیت هر سطر از این شکل دو حالت کلی دارد، سعی کنید از این دو حالت برای چاپ کل جدول استفاده کنید.

راهنمایی ۲

رشته ss وضعیت nn سطر اول و آخر جدول را نمایش می‌دهد. s="XX"+". ."+"XX"s = "X\dots X" + ".\ \dots ." + "X \dots X" رشته tt وضعیت nn سطر میانی جدول را نمایش می‌دهد. t=". ."+"XX"+". ."t = ".\ \dots ." + "X\dots X" + ".\ \dots ."

راهنمایی ۳

شبه کد حل سوال را می‌توانید مشاهده کنید:

for i from 1 to n:
    print s
for i from n + 1 to 2n:
    print t
for i from 2n + 1 to 3n:
    print s
Plain text

خط شکسته


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

امین یک جدول n×mn \times m دارد که هر خانه‌ی آن یکی از کاراکتر‌های .، /، \ یا _ است. هر کاراکتر از این جدول نشان دهنده وضعیت یک خانه 1×11 \times 1 (یا همان مربع واحد) متناظر آن در صفحه است. این جدول در نهایت، یک خط شکسته را نمایش می‌دهد.

کاراکتر . نشان می‌دهد هیچ قسمتی از خط شکسته در مربع واحد متناظر با این خانه وجود ندارد: توضیح تصویر

کاراکتر _ نشان می‌دهد خط شکسته حاوی ضلع پایینی مربع واحد متناظر با این خانه از جدول است: توضیح تصویر

کاراکتر / نشان می‌دهد خط شکسته حاوی قطر فرعی مربع واحد متناظر با این خانه از جدول است: توضیح تصویر

کاراکتر \ نشان می‌دهد خط شکسته حاوی قطر اصلی مربع واحد متناظر با این خانه از جدول است: توضیح تصویر

تضمین می‌شود شکل بدست آمده یک خط شکسته پیوسته است که سمت چپ صفحه را به سمت راست صفحه n×mn \times m متصل می‌کند؛ در واقع صفحه n×mn \times m را به دو قسمت بالایی و پایینی تقسیم می‌کند.

امین می‌خواهد مساحت قسمت پایین ایجاد شده توسط این خط شکسته را محاسبه کند. به او کمک کنید تا این کار را انجام دهد.

ورودی🔗

در سطر اول ورودی یک عدد طبیعی tt آمده که نشان دهنده تعداد مثال‌هایی است که داده می‌شود.

برای هر مثال در سطر اول دو عدد طبیعی nn و mm با فاصله از هم آمده که نشان دهنده ابعاد جدول است. 1n,m1001 \le n, m \le 100 در nn سطر بعدی در هر سطر دقیقاً mm کاراکتر آمده که هر کدام از این کاراکتر‌ها برابر .، /، \ یا _خواهد بود.

تضمین می‌شود ورودی داده شده جدول یک خط شکسته پیوسته است که از سمت چپ جدول شروع شده و به سمت راست جدول ختم می‌شود و در هر ستون دقیقا یک کاراکتر غیر . دارد.

تضمین می‌شود اندازه جدول‌های این tt مثال از 10 00010\ 000 بیشتر نخواهد بود.

خروجی🔗

خروجی برنامه شما tt سطر دارد که در سطر iiام آن مساحت زیر نمودار شکل iiام را با دقت ۳ رقم بعد از اعشار چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

3
3 3
___
...
...
1 1
\
3 5
../\.
_/..\
.....
Plain text

خروجی نمونه ۱🔗

6.000
0.500
9.000
Plain text

شکل‌ مربوط به خط شکسته اول توضیح تصویر

شکل‌ مربوط به خط شکسته سوم توضیح تصویر

ورودی نمونه ۲🔗

1
6 20
....................
../\................
_/..\.........../\..
.....\........./..\_
......\__...../.....
.........\___/......
Plain text

خروجی نمونه ۲🔗

41.500
Plain text

شکل‌ مربوط به خط شکسته داده شده توضیح تصویر

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

اگر مساحت ایجاد شده توسط خط شکسته را برای یک ستون محاسبه کنید می‌توانید پاسخ مسئله را بدست آورید. (چرا؟)

راهنمایی ۲

با توجه به کاراکتری که در هر ستون وجود دارد؛ باید مساحت یک ذوزنقه یا مستطیل را محاسبه کنیم.

راهنمایی ۳

شبه کد حل سوال را می‌توانید مشاهده کنید:

area = 0.0
for column from 1 to m:
    for row from 1 to n:
        if row != '.':
            area += (n - 1 - row)
            if row != '_':
                area += 0.5
print area
Plain text

نعلم کو؟!


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

بهروز نعل اسبش را توی مزرعه گم کرده و می‌خواهد آن را پیدا کند. از آن‌جایی که بهروز ذهن پیچیده‌ای دارد و دوست دارد از هر چیزی یک مسئله بسازد، می‌خواهد بداند نعل اسب چند تا جای مختلف می‌تواند قرار داشته باشد. مزرعه به شکل یک جدول n×mn \times m هست که در هر کدام از خانه‌هایش یا علوفه قرار دارد یا خالی می‌باشد.

پای اسب بهروز کمی عجیب و غریب است و نعل اسبش شکل یک مربع ۳ ×\times ۳ که دو خانه مجاور ضلعی از محیط آن به همراه مرکزش برداشته شده است. در شکل زیر حالت کلی نعل اسب را می‌بینیم که با خانه‌های سیاه مشخص شده است(دقت کنید که ممکن است مکان نعل اسب دوران‌ها و تقارن‌هایی از شکل زیر نیز باشد). توضیح تصویر

می‌دانیم نعل اسب بهروز در بین علوفه‌ها پنهان شده و تعدادی علوفه که به شکل بالا باشند، می‌توانند یک نعل اسب را در خود جای دهند. حال به بهروز کمک کنید تا تعداد مکان‌های مختلف نعل اسب را پیدا کند.

ورودی🔗

در سطر اول ورودی دو عدد nn و mm آمده‌اند که به ترتیب تعداد سطرها و ستون‌های مزرعه ما را نشان می‌دهند.

در iiامین سطر از nn سطر بعدی یک رشته به طول mm متشکل از حروف . و * آمده است. حرف . نشان‌دهنده خانه خالی و حرف * نشان‌دهنده علوفه است. 1n,m1001 \le n, m \le 100

خروجی🔗

در تنها سطر خروجی، پاسخ مسئله را چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

3 3
***
***
*..
Plain text

خروجی نمونه ۱🔗

1
Plain text

ورودی نمونه ۲🔗

3 4
****
.***
.***
Plain text

خروجی نمونه ۲🔗

9
Plain text

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

سعی کنید تمامی دوران‌ها و تقارن‌های شکل نعل اسب را در نظر بگیرید و جداگانه هرکدام را در شکل بشمارید. از این نکته استفاده کنید که در مجموع ۸ شکل مختلف برای شمارش داریم.

راهنمایی ۲

نکته درخور توجه در حل مسئله این است که در محیط هر مربع ۳ * ۳ یا دقیقا یک نعل اسب وجود دارد و یا هیچ نعل اسبی موجود نیست. همچنین هر نعل اسب نیز در محیط دقیقا یک مربع ۳ * ۳ قرار دارد.

بنابراین برای شمارش نعل اسب‌ها خوب است که بر روی مربع‌های ۳ * ۳ حرکت کنیم و به ازای هر کدام از آن‌ها چک کنیم که آیا نعل اسبی در خود دارند یا نه.

راهنمایی ۳

برای حرکت روی مربع‌های ۳ * ۳، هر مربع را با خانه وسط آن متناظر می‌کنیم. بدین صورت با دیدن همه خانه‌هایی که در محیط مستطیلمان نیست، همه مربع‌های ۳ * ۳ موجود را دیده‌ایم.

حال به ازای هر خانه‌ای که مرکز یک مربع است، اگر در هشت خانه واقع در محیط مربع، دقیقا دو خانه وجود داشته باشند که خالی باشند و آن دو خانه هم مجاور ضلعی باشند، این مربع ۳ * ۳ دارای یک نعل اسب می‌باشد.

همچنین برای راحت‌تر چک کردن اینکه دو خانه مجاور ضلعی هستند یا نه، می‌توانید از مجموع قدر مطلق تفاضل شماره سطر و ستون آن دو استفاده کنید؛ این دو خانه مجاور ضلعی هستند اگر و تنها اگر مجموع گفته شده برابر یک باشد.

جاستیفای


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

امین یک متن حاوی nn کلمه دارد و می‌خواهد آن‌ها را مرتب کند برای این کار یک عدد صحیح ww انتخاب کرده و می‌خواهد آن را در سطر‌هایی که ظرفیت حداکثر ww کاراکتر دارند، بنویسد.

برای نوشتن این کلمات به ترتیب داده شده آن‌ها را یادداشت می‌کنیم. از کلمه اول شروع کرده و آن را در ابتدای سطر اول می‌نویسیم. از آن به بعد برای هر کلمه اگر تونستیم آن را با حفظ یک فاصله (یک کاراکتر space یا ' ') از کلمه قبل در همان سطر بنویسیم (با توجه به ظرفیت آن سطر) این کار را انجام می‌دهیم و در غیر این صورت کلمه در ابتدای سطر بعدی نوشته خواهد شد و این روند ادامه پیدا می‌کند.

می‌خواهیم اشکالاتی که در کوچک یا بزرگ بودن حروف وجود دارد را برطرف کنیم. یعنی همه حروف نوشته شده باید کوچک باشند به جز حرف اولِ کلمه‌ی اول جملات. می‌دانیم که جملات با کلماتی ختم می‌شوند که در انتهای آن‌ها . ، ؟ یا ! داشته باشند.

حال می‌خواهیم همه این سطرها را جاستیفای کنیم! یعنی تعداد تقریباً مساوی فاصله بین کلمات هر سطر قرار دهیم تا کلمه‌ی آخر هر سطر به انتهای آن سطر برسد.

اگر یک کلمه در یک سطر باشد آن را در ابتدای سطر می‌نویسیم و بقیه سطر را با کاراکتر space پرکنیم.

در غیر این صورت فرض کنید mm کلمه در یک سطر داشته باشیم. می‌خواهیم در بین m1m-1 فاصله ایجاد شده توسط اینmm کلمه تعدادی کاراکتر space قرار دهیم به طوری که اختلاف تعداد spaceهای موجود در این فواصل حداکثر برابر یک باشد، همچنین کلمه آخر به انتهای سطر رسیده باشد.

به عبارت دیگر برای هر سطر عددی مانند kk وجود دارد که فاصله بین کلمات آن سطر همگی kk یا k+1k + 1 باشد.

فرض کنید برای اینکار باید rr از فاصله‌ها k+1k + 1 اسپیس، و m1rm-1-r تا kk تا اسپیس داشته باشند، می‌خواهیم r2\lfloor \frac{r}{2}\rfloor تا از فواصل k+1k + 1تایی بین کلمات ابتدایی سطر باشد و r2\lceil \frac{r}{2} \rceil تا از فواصل k+1k + 1تایی بین کلمات انتهایی سطر باشد.

در نهایت تعداد کاراکترهای چاپ شده در هر سطر باید دقیقاً ww باشد. با احتساب فاصله‌ها (یا همان spaceها)

ورودی🔗

در ورودی به شما tt مثال داده می‌شود.

1t1001 \le t \le 100

در هر مثال در سطر اول عدد nn و عدد ww داده می‌شود و در سطر دوم nn کلمه با فاصله از هم داده می‌شود.1n1001 \le n \le 100 2w2 0002 \le w \le 2\ 000

هر کلمه رشته حداکثر ۲۰ کاراکتری است که از حروف کوچک و بزرگ انگلیسی تشکیل شده است، به انتهای برخی از کلمات حداکثر یکی از کاراکترهای . یا ؟ یا ! یا, چسبیده است.

تضمین می‌شود آخرین کلمه با یکی از کاراکترهای . یا ؟ یا ! ختم می‌شود.

تضمین می‌شود مقدار ww از طول بزرگ‌ترین کلمه داده شده در هر مثال کمتر نخواهد بود.

خروجی🔗

خروجی خواسته شده در مسئله را مطابق مثال‌ها چاپ کنید. برای نشان دادن ابتدا و انتهای خطوط از کارکتر | مطابق با مثال‌ها استفاده کنید.

مثال🔗

ورودی نمونه ۱🔗

2
2 6
caReEr dAyS!
6 10
Are You Ready For This Question?
Plain text

خروجی نمونه ۱🔗

|Career|
|days! |
|Are    you|
|ready  for|
|this      |
|question? |
Plain text

ورودی نمونه ۲🔗

1
34 20
this is going to be a big sample to show how you should solve this problem. I hope this sample can show you what you want. please, try to solve this problem. love you!
Plain text

خروجی نمونه ۲🔗

|This is going to  be|
|a big sample to show|
|how you should solve|
|this problem. I hope|
|this sample can show|
|you  what you  want.|
|Please, try to solve|
|this  problem.  Love|
|you!                |
Plain text

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

در ابتدا حروف انگلیسی بزرگ در تمام کلمات را به حروف کوچک تبدیل کنیم. سپس حرف اول کلمه اول متن و حرف اول (در صورت وجود) بعد از هر کاراکتر .، ! یا ؟ را به بزرگ تغییر می‌دهیم.

در واقع آغاز یک جمله را از پایان جمله قبلی تشخیض می‌دهیم.

راهنمایی ۲

بعد از درست کردن کوچک یا بزرگ بودن کلمات مطابق با الگوریتم گفته شده در سوال کلمات را در خطوط مختلف می‌ریزیم.

حال برای هر خط مطابق با الگوریتم بیان شده در سوال تعدادی فاصله بین کلمات قرار می‌دهیم تا به رشته مطلوب دست پیدا کنیم.

راهنمایی ۳

فرض کنید کلمات در یک تست داده شده s1,s2,s3,,sns_1, s_2, s_3, \dots, s_n باشد.

for i from 1 to n:
    change upper_case letter of s[i] to lower_case

change first letter of s[0] to upper_case
for i from 1 to n - 1:
    if s[i] ends with '.' or '!' or '?':
         change first letter of s[i + 1] to upper_case

for i from 1 to n:
    if can add s[i] to this_line without exceed w:
        add s[i] to this_line
    else:
        add this_line to all_lines
        make this_lines clear

for each line in all_lines:
    justify(line, w)
Plain text

حال فرض کنید می‌خواهیم برای یک خط دستور justify را پیاده سازی کنیم. اکنون فرض کنید l1,l2,l3,lml_1, l_2, l_3 \dots, l_m کلمات یک خط باشد.

if m = 1:
    print '|' + l[1] + ' ' * (w - (length of l[1])) + '|'
else: 
    spaces = w - (sum of length l[i] for all i from 1 to m)

    for i from 1 to m - 1:
        x[i] = floor(spaces / (m - 1))
    remaining_space = space % (m - 1)

    for i from 1 to floor(m / 2):
        x[i] = x[i] + 1

    for i from 1 to ceil(m / 2):
        x[m - i] = x[m - i] + 1

    print '|'
    for i from 1 to m - 1:
        print l[i]
        print ' ' * x[i]
    print l[m] + '|'
Plain text

مسابقه پیچیده


  • محدودیت زمان: ۴ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

عرفان به تازگی با مسابقه QFC آشنا شده و تصمیم گرفته امسال در این رقابت‌ شرکت کند؛ از شانس خوب او با آمدن کرونا، این مسابقه به صورت آنلاین برگزار می‌شود و عرفان که با مسئول برگزاری این مسابقه دوست است می‌خواهد با کمک او بیشترین سود را از این مسابقه ببرد. نحوه برگزاری مسابقه‌ به شرح زیر است:

درون مسابقه دقیقا ۱۰ سوال قرار دارد و شرکت‌کنندگان ۳۰۰ دقیقه وقت دارند تا سوالات را حل کنند. بعد از اتمام مسابقه هر شرکت‌کننده تعدادی سوال را حل می‌کند (این تعداد می‌تواند صفر باشد) و به ازای هر سوال حل شده، تعداد ارسال‌های اشتباه و زمان حل سوال توسط آن فرد را داریم.

شرکت‌کنندگان به ترتیب اولویت زیر، رتبه‌بندی می‌شوند:

  • فردی که سوال بیشتری حل کرده رتبه بهتری می‌گیرد.
  • در صورت برابری تعداد سوالات حل شده، افراد بر حسب جریمه زمانی مرتب می‌شوند. منظور از جریمه زمانی هر سوال، زمانی که طول کشیده تا آن فرد سوال را حل کند، به علاوه تعداد ارسال‌های اشتباه آن فرد برای آن سوال، ضرب در ۲۰ است. جریمه زمانی یک فرد هم مجموع جریمه‌های زمانی سوالات حل شده توسط اوست.
  • در صورت برابری در جریمه زمانی دو فرد، زمان حل سوالات توسط آن‌ها را به صورت نزولی در نظر می‌گیریم و آن‌ دو را به ترتیب لغت‌نامه‌ای بررسی می‌کنیم؛ یعنی یک آرایه از یک آرایه دیگر کوچک‌تر است اگر در اولین اندیسی که آن دو با هم فرق دارند، عضو مربوط به آرایه اول کوچک‌تر باشد (یعنی اگر آخرین زمان حل فرد اول دقیقه ۳۰۰ باشد و زمان حل فرد دوم دقیقه ۲۹۰ باشد، فرد دوم رتبه بهتری کسب می‌کند)
  • در صورت برابری در آرایه زمان حل مسئول مسابقه، فرد بهتر را مشخص می‌کند که چون عرفان با او رفیق است، می‌توانید فرض کنید او رتبه برتر را کسب می‌کند.

هم‌چنین در پایان مسابقه به افراد، طبق قوانین زیر دلار پرداخت می‌شود.

  • فرد با رتبه rr، 5000/r\lfloor 5000/r \rfloor دلار جایزه می‌گیرد. توجه کنید که رتبه بهترین فرد ۱ است.
  • بعد از آن به افراد زیر مدال داده می‌شود (تضمین می‌شود تعداد افراد شرکت‌کننده حتما مضرب ۱۰ است).
    • افراد با رتبه‌های ۱ تا n/10\lfloor n/10 \rfloor، مدال طلا به همراه ۱۲۰۰ دلار پول می‌گیرند.
    • افراد بعدی تا رتبه 3n/10\lfloor 3n/10 \rfloor، مدال نقره به همراه ۸۰۰ دلار پول می‌گیرند.
    • افراد بعدی تا رتبه 6n/10\lfloor 6n/10 \rfloor، مدال برنز به همراه ۴۰۰ دلار پول می‌گیرند.
  • به ازای هر سوال، فردی که اولین بار آن را حل کند، ۸۰۰ دلار پول می‌گیرد.
  • اولین ارسال درست در کل زمان مسابقه هم ۷۰۰ دلار جایزه دارد.
  • آخرین ارسال درست در زمان مسابقه هم ۵۰۰ دلار جایزه دارد.

در صورت برابری در سه مورد آخر، باز هم مسئول مسابقه وظیفه دارد برنده را مشخص کند و طبیعتا در صورت امکان عرفان را انتخاب می‌کند. یعنی در صورتی که چند نفر، هم‌زمان یک سوال را به عنوان نفر اول حل کنند، مسئول مسابقه می‌تواند جایزه را به عرفان دهد.

حال عرفان قبل از شروع مسابقه، سوالات را از مسئول مسابقه گرفته و به ازای هر سوال می‌داند اگر بخواهد کد آن را بزند چند دقیقه طول می‌کشد و در مجموع چند ارسال اشتباه خواهد داشت. ممکن است عرفان هرگز نتواند کد آن سوال را بزند!

هم‌چنین عرفان به ازای هر فرد، می‌داند که چه سوالاتی حل می‌کند و زمان و تعداد پاسخ‌های فرستاده شده توسط آن فرد را دارد. توجه کنید برای این که تقلب کردن عرفان مشخص نشود،‌ او باید همیشه کد بزند، مگر این که دیگر نتواند سوالی را حل کند! هم‌چنین عرفان نمی‌تواند بعد از دقیقه ۳۰۰ هیچ کدی ارسال کند.

حال عرفان از شما می‌خواهد تا به او بگویید از بین همه حالاتی که برای ترتیب حل سوالات توسط او وجود دارد، حداکثر چه مقداری پول می‌تواند به دست بیاورد.

ورودی🔗

در خط اول ورودی تعداد شرکت‌کننده‌ها، nn، می‌آید. تضمین می‌شود nn مضرب ۱۰ است.

سپس در n1n - 1 خط بعدی اطلاعات شرکت‌کردن همه شرکت‌کننده‌ها به جز عرفان می‌آید. در هر خط وضعیت حل هر سوال توسط آن فرد می‌آید که با , از هم جدا شده است. یعنی به ازای هر سوال، اگر توسط آن فرد حل نشده بود، - و در غیر این صورت دو عدد tt و ww به ترتیب می‌آید که نشان‌دهنده زمان حل آن سوال توسط آن فرد و تعداد ارسال‌های اشتباه اوست.

سپس در خط آخر، اطلاعات حل سوالات توسط عرفان می‌آید. اگر عرفان نمی‌توانست آن سوال را حل کند،‌ - و در غیر این صورت به ترتیب، زمان مورد نیاز برای زدن کد آن سوال و تعداد پاسخ‌های نادرست او می‌آید.

10n10010 \le n \le 100 1t3001 \le t \le 300 0w100 \le w \le 10

خروجی🔗

در یک خط حداکثر پولی که عرفان می‌تواند به دست آورد را چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

10
232 1,-,-,6 7,253 4,173 5,117 1,-,-,85 3
-,231 0,167 0,257 7,-,-,125 4,283 0,215 4,-
41 1,-,290 8,-,-,-,-,243 7,120 3,184 9
142 8,243 7,69 0,-,41 9,-,278 1,264 4,-,74 9
53 8,-,187 9,60 1,48 8,98 10,-,-,55 7,259 5
250 0,-,-,-,166 0,16 3,-,82 4,73 0,183 3
-,-,-,-,105 3,-,-,-,152 4,-
-,84 5,98 8,-,120 8,240 3,94 1,-,28 7,109 8
280 6,246 5,58 9,-,-,-,-,-,-,-
38 10,-,227 10,187 9,182 1,-,203 9,253 7,-,-
Plain text

خروجی نمونه ۱🔗

1800
Plain text

ورودی نمونه ۲🔗

10
232 1,-,-,6 7,253 4,173 5,117 1,-,-,85 3
-,231 0,167 0,257 7,-,-,125 4,283 0,215 4,-
41 1,-,290 8,-,-,-,-,243 7,120 3,184 9
142 8,243 7,69 0,-,41 9,-,278 1,264 4,-,74 9
53 8,-,187 9,60 1,48 8,98 10,-,-,55 7,259 5
250 0,-,-,-,166 0,16 3,-,82 4,73 0,183 3
-,-,-,-,105 3,-,-,-,152 4,-
-,84 5,98 8,-,120 8,240 3,94 1,-,28 7,109 8
280 6,246 5,58 9,-,-,-,-,-,-,-
38 10,-,20 10,187 9,20 1,-,203 9,40 7,-,30 4
Plain text

خروجی نمونه ۲🔗

3614
Plain text

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

اولا که حالات مختلفی که عرفان می‌تواند، سوالات را حل کند حداکثر 10!10! است، بنابراین می‌توانیم به ازای هر حالت، بررسی کنیم که چند دلار پول می‌گیرد.

حال سعی می‌کنیم که به ازای یک حالت بررسی کنیم عرفان چند دلار پول می‌گیرد. برای این کار دو کلاس Contestant و ‍‍Problem تعریف می‌کنیم و سعی می‌کنیم با کمک آن‌ها کد سوال را بزنیم.

اولین کاری که باید برای حل سوال بکنید این است که یک تابع بنویسید که با گرفتن دو شی از نوع Contestant تشخیص دهد که کدام رتبه بهتری کسب می‌کند. برای این کار پیشنهاد می‌کنیم بخش رتبه‌بندی را با دقت بخوانید و سپس موارد گفته شده را پیاده‌سازی کنید.

راهنمایی ۲

اولا که کلاس Contestant باید ویژگی‌های زیر را داشته باشد:

  • یک لیست ده تایی از Problem ها
  • تعداد سوالات حل شده
  • میزان پنالتی کلی
  • یک متغیر بولی که مشخص می‌کند این شرکت‌کننده همان عرفان است یا نه.

خود Problem هم ویژگی‌های زیر را دارد.

  • یک متغیر بولی که مشخص می‌کند سوال حل شده یا نه.
  • زمان حل سوال
  • تعداد ارسال‌های اشتباه برای حل سوال

حال می‌توان با خواندن رشته‌های ورودی اشیا لازم برای nn شرکت‌کننده را ساخت. سپس می‌توانید از روی قوانین گفته شده به راحتی تابعی بنویسید که دو شرکت‌کننده را با هم مقایسه کند.

راهنمایی ۳

می‌توانید یک نمونه پیاده‌سازی در زبان C++ را ازینجا ببینید.

داده‌داری


  • محدودیت زمان: ۳ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

امیرمحمد به دلیل اوضاع فعلی،‌ در خانه مانده و حوصله‌اش سر رفته است. او می‌خواهد برای ایجاد سرگرمی و مفید بودن، سیستمی طراحی کند که مانند یک دیتابیس عمل می‌کند.

هر دیتابیس شامل چند جدول است که از طریق اسم هر جدول، می‌توان به آن دسترسی داشت. خود هر جدول شامل چند سطر و چند ستون است؛ به طوری که هر ستون یک عنوان و یک جنس دارد که می‌تواند رشته یا عدد باشد و محتواهای آن ستون حتما باید از آن جنس باشند.

امیرمحمد می‌خواهد برای سیستمش، بخش مدیریت کاربر نیز بگذارد به این‌صورت که دو سطح دسترسی editor و viewer وجود داشته باشد. کاربر با سطح دسترسی editor می‌تواند تمام دستورات را انجام دهد ولی کاربر با دسترسی viewer تنها می‌تواند دستورات print و search را انجام دهد (در ادامه تعریف این دو دستور آمده است) و اگر درخواست انجام دستور دیگری به غیر از این ۲ نوع دستور را داشت، باید عبارت access denied را چاپ شود.

در ادامه دستورات موجود در این سیستم را می‌بینید:

دستور اضافه کردن کاربر🔗

create user username editor
create user username viewer
Plain text

این دستور به این معناست که یک کاربر جدید با نام کاربری username و سطح دسترسی گفته شده، به سیستم اضافه شود. username یک رشته شامل حروف کوچک انگلیسی می‌باشد و تضمین می‌شود که هیچ دو کاربری،‌ نام کاربری یکسان ندارند. تضمین‌ می‌شود در هر کوئری کاربری که درخواست می‌دهد، حتما وجود داشته باشد.

دستور ایجاد و حذف کردن جدول🔗

برای ایجاد و یا حذف یک جدول به ترتیب از دستورهای زیر استفاده می‌شود:

create table table_name username
delete table table_name username
Plain text

که به ترتیب بیانگر این می‌باشد که کاربر با نام کاربری username درخواست اضافه‌کردن و یا حذف یک جدول با نام table_name را داده است.

همچنین در ابتدا هر جدول که تعریف می‌شود، هیچ سطر و ستونی وجود ندارد و در ادامه می‌توان به آن، سطر و ستون اضافه کرد.

اضافه و حدف کردن ستون🔗

برای اضافه کردن ستون به سمت راست جدول، از دستور زیر استفاده می‌شود:

add column table_name column_name int username
add column table_name column_name string username
Plain text

که بیانگر این می‌باشد کاربر با نام کاربری username به ترتیب، درخواستی برای ایجاد یک ستون با نام column_name در جدول table_name کرده و جنس آن ستون هم در کلمه پنجم مشخص می‌شود؛ هنگامی که یک ستون اضافه می‌شود، در صورتی از جنس عدد باشد، سطرهای این ستون با مقدار ۰ و در غیراینصورت با رشته null پر می‌شوند. (توجه کنید که منظور از رشته‌ی null، یک رشته‌ی به طول ۴ می‌باشد و نه رشته‌ی تهی!)

همچنین تضمین می‌شود در این فرآیند، هیچوقت دو ستون هم‌نام باهم در یک جدول وجود ندارند و هم‌زمان هیچ دو جدولی نام یکسان نیز ندارند.

دستور بعدی، برای حذف کردن یک ستون از جدول می‌باشد:

remove column table_name column_name username
Plain text

که بیانگر این است کاربر با نام کاربری username درخواست حذف ستون با نام column_name در جدول با نام table_name را داده است.

اضافه و حذف کردن سطر🔗

کاربر با نام کاربری username برای اضافه کردن یک سطر به آخر جدول با نام table_name از دستور زیر استفاده می‌کند (در هنگام استفاده از این کوئری تضمین می‌شود حداقل یک ستون در جدول وجود دارد):

add row table_name username
Plain text

توجه کنید که وقتی یک سطر اضافه می‌شود، در ستون‌هایی که از جنس عدد باشند، مقدار ۰ و در باقی ستون‌ها رشته null گذاشته می‌شود.(توجه کنید که منظور از رشته‌ی null، یک رشته‌ی به طول ۴ می‌باشد و نه رشته‌ی تهی!)

همچنین کاربر با نام کاربری username در جدول table_name برای حذف کردن یک ردیف که از بالا به پایین، iiامین سطر می‌باشد، از دستور زیر استفاده میکند:

remove row table_name i username
Plain text

تغییر دادن مقدار یک خانه🔗

کاربر با نام کاربری username برای تغییر مقدار خانه واقع در سطر iiام و ستون با نام column_name در جدول table_name به مقدار value از دستور زیر استفاده می‌کند:

change table_name i column_name value username
Plain text

توجه کنید که اگر این ستون از جنس عدد باشد، value عدد است و در غیراینصورت یک رشته از حروف کوچک انگلیسی است.

چاپ کردن🔗

این سیستم قابلیت این را دارد که بتوان چند ستون از یک جدول را مشخص کرد و جدول را بر اساس ستون‌های مشخص شده، به ترتیب اولویت مرتب کرد و در نهایت چاپ کرد.

برای این‌کار اگر کاربر با نام کاربری username بخواهد جدول با نام table_name را بر اساس ستون‌های با نام‌های col_1، col_2،...، col_k مرتب کند و سپس جدول را خروجی دهد، از دستور زیر استفاده می‌کند:

print table_name col_1 col_2 ... col_k username
Plain text

در این دستور، شما باید ردیف‌های جدول را به ترتیب بر اساس ستون‌های col_1، col_2،...،col_k به ترتیب صعودی مرتب کنید. یعنی ابتدا برحسب ستون col_1 مرتب کنید، سپس ردیف‌هایی که مقدارشان در ستون col_1 برابر بود، بر اساس مقدارشان در ستون col_2 مرتب کنید و... . همچنین در نهایت اگر دو سطر تمامی مقادیرشان در این kk ستون یکسان بود، بر اساس زمان اضافه شدن سطرها به جدول مرتب‌شان کنید (یا به عبارتی دیگر بر اساس اندیس سطرها در جدول اولیه).

در نظر داشته باشید که ترتیب ردیف‌ها در جدول اصلی عوض نمی‌شود، و با این درخواست صرفا باید جدول مرتب شده بر اساس اولویت‌ها خروجی داده شود.

توجه کنید که اگر یک ستون از جنس رشته باشد، مقادیر آن بر اساس ترتیب کتابخانه‌ای به صورت صعودی مرتب می‌شوند و در غیر این صورت بر حسب مقدار عددی مرتب می‌شوند.

کاربر با نام کاربری username برای خروجی دادن کل جدول table_name از دستور زیر استفاده می‌کند: (توجه کنید که در این دستور، سطرهای جدول باید به ترتیب زمان اضافه شدن به جدول، چاپ شوند و نیازی به مرتب‌سازی نیست)

print table_name * username
Plain text

جست‌وجو در جدول🔗

این سیستم، قابلیت جست‌وجو بر حسب یک پارامتر خاص نیز دارد. به این صورت که کاربر با نام کاربری username درخواست می‌دهد تا تمامی سطرهای جدول table_name، که مقدار آن‌ها در ستون با نام column_name دقیقا برابر با value است، چاپ شوند (توجه کنید که تمامی عناصر آن سطر باید چاپ شوند). برای اینکار از دستور زیر استفاده می‌کند: (در این دستور، سطرهای جدول باید به ترتیب زمان اضافه شدن به جدول، چاپ شوند)

search table_name column_name value username
Plain text

همچنین اگر این ستون از جنس عدد باشد،‌ value یک عدد است و اگر جنس این ستون رشته باشد، value یک رشته است.

تضمین می‌شود که تنها از دستورات بالا داده می‌شود و هنگامی که درخواستی داده می‌شود، تمامی ستون‌ها و جدول‌هایی که در آن دستور قید شده‌اند، وجود دارند و همچنین هیچ دو جدول و هیچ دو ستونی با نام یکسان هم‌زمان وجود ندارند.

در نهایت پس از پایان عملیا‌ت‌ها، در خط‌ آخر ورودی عبارت done می‌آید.

پیشنهاد می‌شود حتما به ورودی‌ نمونه و پاسخ‌ آن دقت کنید.

ورودی🔗

ورودی شامل تعدادی خط می‌باشد، که در هر خط، یکی از دستوراتی که در بالا تعریف شده‌اند، آمده است.

همچنین در نهایت، در خط آخر ورودی، عبارت done می‌آید که برای تشخیص تمام شدن ورودی‌ها می‌باشد.

تضمین می‌شود مجموع کاراکتر‌های ورودی حداکثر 40 00040\ 000 می‌باشد.

همچنین تمامی رشته‌ها، شامل حروف کوچک انگلیسی می‌باشند و هیچکدام از اسم‌های جدول‌ها، ستون‌ها و... شامل فاصله (space) نمی‌باشد.

تمامی دستورات معتبر می‌باشند یعنی اگر اسم جدول یا ستون یا... در یکی از دستورات آورده شود، تضمین می‌شود حتما آن جدول، ستون یا... وجود دارد.

خانه‌هایی از جدول که از جنس عدد باشند، در بازه‌ی [109,109][-10^9, 10^9] می‌باشند و همچنین طول رشته‌ها کمتر مساوی ۵۰ می‌باشد.

خروجی🔗

به ازای هر دستور مربوط به print و search، جدول را مطابق با دستور داده شده خروجی دهید.

توجه کنید که در خروجی، نام ستون‌ها را نباید چاپ کنید و همچنین هر سطر در یک خط چاپ شود و در هر خط بین مقادیر دو ستون متوالی باید دقیقا یک فاصله (space) باشد.

برای درک بهتر، به مثال‌های نمونه توجه کنید.

مثال🔗

ورودی نمونه ۱🔗

create user amin editor
create user sajad viewer
create table yek sajad
create table do amin
create table jadval amin
delete table do amin
add column jadval yek int amin
add column jadval do string amin
add column jadval se int amin
add row jadval amin
search jadval se 0 amin
add row jadval amin
print jadval * amin
add row jadval amin
change jadval 1 do salam amin
change jadval 2 yek -3 amin
print jadval yek do amin
remove row jadval 3 amin
remove column jadval do amin
change jadval 1 yek 3 amin
print jadval * amin
search jadval yek 3 amin
done
Plain text

خروجی نمونه ۱🔗

access denied
0 null 0
0 null 0
0 null 0
-3 null 0
0 null 0
0 salam 0
3 0
-3 0
3 0
Plain text

در ابتدا هنگامی که کاربر sajad درخواست ساخت جدول می‌دهد، access denied چاپ می‌شود.

در دستورات print و ‍‍‍search که در ادامه آمده‌اند، به ترتیب خروجی‌های زیر چاپ می‌شوند:

0 null 0
Plain text
0 null 0
0 null 0
Plain text
-3 null 0
0 null 0
0 salam 0
Plain text
3 0
-3 0
Plain text
3 0
Plain text

قسمت آموزشی🔗

در این قسمت راهنمایی‌های سوال، به مرور اضافه می‌شود. مشکلات‌تان در راستای حل سوال را می‌توانید از بخش "سوال بپرسید" مطرح کنید.

راهنمایی ۱

برای پیاده‌سازی راحت‌تر و اصولی‌تر این سوال، باید سعی کنید از ساختار شی‌گرایی استفاده کنید.

برای این منظور، می‌توانید یک کلاس داشته باشید که در آن مدیریت جدول‌ها (نگهداری لیست جدول‌ها و حذف و اضافه کردن جدول) انجام شود. همچنین برای هر جدول می‌‌توانید یک کلاس داشته باشید که اطلاعات جدول از قبیل نام ستون‌ها و جنس آن‌ها، محتوای درون هر ردیف یا ستون و... را نگهداری کند.

همچنین برای هر کدام از درخواست‌های سوال که مربوط به ایجاد تغییرات در جدول و یا چاپ و جست‌وجو می‌باشد، یک تابع تعریف کنید که بتواند آن کار را انجام دهد.

راهنمایی ۲

یکی دیگر از بخش‌های این سوال که چالش برانگیز است، این است که چگونه ورودی را بخوانیم و تشخیص دهیم که کدام دستور را باید انجام دهیم و اینکه آیا کاربری که کار مورد نظر را می‌خواهد بکند،‌ دسترسی کافی دارد یا نه (برای تشخیص اینکه access denied چاپ کنیم یا کار مورد نظر را انجام دهیم).

در هر مرحله، هر خط را ورودی می‌گیریم‌ و سپس کلمه‌های آن را بر حسب کاراکتر فاصله (space) از هم جدا می‌کنیم. برای اینکار می‌توانیم خودمان یک تابع بنویسیم که یک رشته ورودی بگیرد و یک آرایه از رشته‌ها خروجی بدهد و یا همچنین می‌توانیم از تابع split استفاده کنیم که در اکثر زبان‌ها وجود دارد.

برای مثال اگر رشته‌ی world is good را به آن بدهید و بخواهید بر اساس فاصله جدا کنید، خروجی یک آرایه شامل ۳ عضو world ، is و good می‌باشد.

ابتدا برای چک کردن اینکه درخواست معتبر می‌باشد یا نه، عضو آخر آرایه را می‌گیرید (عضو آخر، دقیقا همان username می‌باشد) و اگر عضو اول آرایه، برابر print یا search نبود، باید چک کنید که username مورد نظر دسترسی editor دارد یا نه.

همچنین برای انجام بقیه دستور‌ها هم مشابه بالا می‌توانید کار کنید، یعنی با استفاده از دستور‌های شرطی (if)، ابتدا برحسب عضو اول آرایه، حالت بندی کنید، سپس دستورهایی که ممکن است کلمه اولشان یکسان باشد را برحسب کلمه دوم یا... مقایسه کنید. به این صورت به سادگی می‌توانید دستورهای مختلف را از هم جدا کنید.

راهنمایی ۳

در بخش راهنمایی، میخواهیم به نحوه پیاده سازی دستور چاپ کردن جدول بپردازیم.

هنگامی که هر خط ورودی را بر اساس فاصله (space) جدا کنید، در صورتی که کلمه اول برابر با print باشد، باید جدول را چاپ کنید، اما دو نوع دستور مختلف وجود دارد برای این‌کار.

در صورتی که کلمه‌ی سوم برابر با * باشد، باید تمامی جدول را خروجی دهید و در غیراینصورت باید جدول را به نوع دیگر خروجی دهید. یعنی بر اساس اولویت مرتب سازی کنید.

فرض کنید اولویت اول برحسب ستون col_1، اولویت دوم برحسب ستون col_2 و در نهایت اولویت kkام برحسب ستون col_k باشد.

می‌توانید با استفاده از نوشتن یک تابع compare این‌کار را انجام دهید. کار این تابع به این صورت می‌باشد که دو عنصر می‌گیرد و سپس خروجی‌اش این است که عنصر اول بزرگتر است یا عنصر دوم بزرگتر است یا هر دو عنصر مساوی می‌باشند. شما می‌توانید با استفاده از یک حلقه، به ترتیب این دو عنصر را برحسب اولویت‌ها مقایسه کنید.

همچنین روش دوم برای این‌کار، این است که ابتدا همه‌ی سطرها را بر حسب اولویت kkام مرتب کنید. سپس همه‌ی سطر‌ها را بر حسب اولویت k1k - 1 ام مرتب کنید و در نهایت بر حسب اولویت اول مرتب کنید.

توجه کنید که در هر کدام از این دو روش، مرتب‌سازی‌ای که انجام می‌دهید، باید stable باشد، یعنی اگر در یکی از مراحل، سطری اندیس ii و سطر دیگری اندیس jj داشته باشد (i<ji < j)، در مرحله‌ی بعد پس از مرتب سازی،‌ در صورتی که این دو سطر در تمامی اولویت‌ها باهم برابر باشند، باز هم سطری که در مرحله‌ی پیش اندیس ii داشت، پیش از سطر دیگری آمده باشد. یعنی ترتیب سطر‌های برابر عوض نشوند.