Let's Learn it Together !

ِAn educational blog from FCIS'2011 students ..

ازاي ممكن نسجل على موقع SPOJ ؟؟

هو الأول ايه SPOJ ده ؟؟

عبارة عن موقع عليه أسئلة زي ال UVa بالظبط ، هو برده online judge

طب أسجل عليه ازاي؟؟


1. ادخل على الموقع : http://www.spoj.pl/
2. اختار register  من فوق على الشمال 
3.     هتجيلك الصفحة دي
4.     فيها اكتب الاسم اللي هتستعمله عشان تدخل ، وهو ده الhandle  اللي هتكتبه في فورم تسجيل المسابقة
5.     بعد ما تكتبه ، اضغط continue
6.     هتطلعلك دي:
 
1.     الاسم اللي انت اختارته
2.     اسمك الحقيقي
3.     اكتب ايميلك
4.     اختاره لو عايز اي حد يقدر يشوف ايميلك
5.     اختاره لو عايز يبعتلك نتيجة المسائل اللي هتحلها على الميل
6.     اختاره لو عايز يبعتلك على الميل لما يكون في مسابقات مهمة
7.      اختاره لو عايز يبعتلك اخر اخبار الموقع
8.     اختاره لو مش عايز اسمك يبان في الranklist بتاعة كل الناس
9.     اختاره لو عايز الeditor  اللي هتكتب الكود فيه ميكونش متطور
10.    متختاروش
11.    اكتب كلمة السر بتاعتك :D
12.    اكتبها تاني
13.    اختار بلدك
14.                        .
15.    اختار c++
16.    دوس update
7.     هتطلعلك الشاشة دي
 
8.     روح الميل بتاعك هتلاقي وصل ميل ، دوس على اللينك اللي فيه وبس كده :D

Do Your Best !

This is one of my nicest-ever experiences with programming. My cousin asked me about the 3-7-10 problem, do you know it? Most probably yes... I'll remind you. You have 3 unmetered containers with capacities 3 liters, 7 liters and 10 liters. Use them to have 5 liters in the 7-liters one and 5 liters in the 10-liters one. You're only allowed to either fill a container or evacuate it – no fractions of any container can be acquired. You have only 10 liters in the 10-liters container, the other two are vacant. No extra water is allowed.


I solved it quickly, but – as you know – just by trial and error. Then I thought about it a little bit... this is a typical backtracking problem. You proceed with one of the solutions, till it either proves correct or you find your last step irrelevant. Instead of quitting the whole solution, you just throw away your last step and choose another one.

Let's learn together ;-). Once you do a step, what can cause it to be “irrelevant”? The answer is very simple: You've reached this configuration before. A configuration is my term to describe the current state, meaning: [Container_3 contains 2 liters, Container_7 contains 4 liters, Container_10 contains 4 liters]. This is a valid configuration, since the sum of the contents is correctly 10 liters.

Note that if you do a step that reaches a configuration you've seen before, you're not advised to do it again – otherwise you'll keep looping forever, reaching the same configuration over and over again.

There's another obvious configuration that makes you stop: The winning configuration. If the next configuration is what you're seeking (0-5-5), just print the solution vector out.

What's the solution vector? I simply keep the configurations with me as I go. Whenever I advance, I add the last configuration hoping that I'll reach the correct one. Whenever I reach a dead end, I just throw that configuration away (from the solution vector) and pick another. Whenever I reach the winning configuration, I print all what I have.

An important notice: Whenever I reach the winning configuration, I print out the solution then discard the last step (though it was correct)! Why? Because I'm seeking all possible solutions, not just one. So I just go on normally – as if nothing has happened – discarding the last trial and proceeding with the next one… may be the next one will lead me to another solution.

The final thing to know is: Given a configuration we're currently in, what are the allowed steps? This is trivial... why are you asking me!? :-P

The allowed moves are – as you know: Pour Container_3 into  Container_7, Container_3 into  Container_10, Container_7 into  Container_3, Container_7 into  Container_10, Container_10 into  Container_3, or Container_10 into  Container_7. Thus, at each iteration, I try these six in order. That's all...

A final notice: Take care of overflowing while pouring. I mean, when you pour Container_7 that currently contains 4 liters (for example) into Container_3 that currently contains 1 liter, take care to leave Container_7 with 2 liters and Container_3 full. This is the meaning of using min() and max() in my solution.

I've said this was one of my nicest-ever experiences because I coded this problem, pressed Ctrl+F5, and found all the 20 solutions on the screen. No debugging, no tracing, nothing. It just worked from the first trial. Only then that I realized I've finally understood backtracking, since this was my first program to write using backtracking.

That said, my solution is not at all generic. You're encouraged to make it more generic, or – more importantly – to expand it. This idea can work for any given containers and any target configuration. I preferred to let this exercise to you. I even didn't try to optimize the code so as not to obscure it.

I'm sharing the solution with you. I've commented it as much as I can, and I'm willing to discuss with you in case it's not that clear.

#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;

ofstream fout("solutions.txt");
static int counter = 1;

struct configuration {
       int contents_3, contents_7, contents_10;

       configuration(int contents_3, int contents_7, int contents_10) {
              this->contents_3 = contents_3;
              this->contents_7 = contents_7;
              this->contents_10 = contents_10;
       }

       bool const operator==(const configuration& other) const {
              return (this->contents_3 == other.contents_3 && this->contents_7 == other.contents_7 && this->contents_10 == other.contents_10);
       }
};

vector<configuration> solution;

void solve(configuration current) {
       // Firstly... have we reached the required configuration?
       if (current.contents_3 == 0 && current.contents_7 == 5 && current.contents_10 == 5) {
              solution.push_back(current); // Add it in preparation for printing the complete solution.

              // Printing the solution.
              {
                     fout << "Solution " << counter++ << ":" << endl;

                     for (vector<configuration>::const_iterator cit = solution.begin(); cit != solution.end(); cit++)
                           fout << cit->contents_3 << " " << cit->contents_7 << " " << cit->contents_10 << endl;

                     fout << endl;
              }

              solution.pop_back(); // Backtrack to search for other solutions.
       } else { // Not yet, let's continue...
              if (find(solution.begin(), solution.end(), current) != solution.end()) // Have we encountered this configuration before?
                     return; // If yes, return instantly. A configuration can never repeat, because if this happens then we are stuck in an infinite loop.

              solution.push_back(current); // Let's assume this is a correct guess...

              //================================//
              // Trying the six allowable moves //
              //================================//

              // Pouring into contents_3...
              {
                     solve(configuration( // ...contents_7.
                           min(3, current.contents_3 + current.contents_7),
                           max(0, current.contents_7 - (3 - current.contents_3)),
                            current.contents_10));

                     solve(configuration( // ...contents_10.
                           min(3, current.contents_3 + current.contents_10),
                           current.contents_7,
                           max(0, current.contents_10 - (3 - current.contents_3))));
              }

              // Pouring into contents_7...
              {
                     solve(configuration( // ...contents_3.
                           max(0, current.contents_3 - (7 - current.contents_7)),
                           min(7, current.contents_7 + current.contents_3),
                           current.contents_10));

                     solve(configuration( // ...contents_10.
                           current.contents_3,
                           min(7, current.contents_7 + current.contents_10),
                           max(0, current.contents_10 - (7 - current.contents_7))));
              }

              // Pouring into contents_10...
              {
                     solve(configuration( // ...contents_3.
                           max(0, current.contents_3 - (10 - current.contents_10)),
                           current.contents_7,
                           min(10, current.contents_10 + current.contents_3)));

                     solve(configuration( // ...contents_7.
                           current.contents_3,
                           max(0, current.contents_7 - (10 - current.contents_10)),
                           min(10, current.contents_10 + current.contents_7)));
              }

              solution.pop_back(); // Backtrack. Either this was a good guess and the solution was already output, or it was bad and thus useless. In both cases, remove it from our vector.
       }
}

int main() {
       solve(configuration(0, 0, 10));
       fout.close();
       return 0;
}


هذا الموضوع مقسم كالتالى:
  1. تاريخ المسابقة ومراحلها.
  2. 5 ساعات من التحدى.
  3. فوائد المشاركة فى المسابقة.
  4. نصائح للفريق. 
 

تاريخ المسابقة ومراحلها:

بدأت ال ACM بتنظيم المسابقات البرمجية الجامعية العالمية " International Collegiate Programming Contest ICPC" منذ عام 1977, وتتكون المسابقة من ثلاث مراحل:
  1. Local Contest: ويتم بها اختيار الفريق الذى سيمثل الكلية.
  2. Regional Contest: ويتم بها اختيار الفريق الذى سيمثل الاقليم فى النهائيات العالمية, ونحن نتبع أقليم العرب وشمال أفريقيا "The Arab & North Africa Regional Programming Contest ANARC".
  3. World Finals: ويتسابق فيها الفرق المؤهلة من ال Regionals حول العالم, ويتم اختيار الفريق بطل العالم.
شعار المسابقة Think, Create, Solve, Observe & Get Balloon.



5 ساعات من التحدي :

مدة المسابقة 5 ساعات, كل فريق مكون من 3 أفراد وجهاز كمبيوتر واحد, وبالتالى فإن عدد أفراد الفريق يساوى 4 ... لا تستغرب, فجهاز الكمبيوتر فرد مهم جدا فى الفريق, ويجب استغلاله بصورة جيدة, حتى تتمكن من الفوز.
يتراوح عدد ال Problems فى المسابقة بين 8 - 12, يقوم الفريق بحلّ المسألة وارسال الكود عبر برنامج PC^2 لل Judge, وينتظر منه الرد اذا كان الحلّ صحيحا أم خطأ, اذا كان الحل صحيحا فان الفريق يحصل على بالونة.


 فى المسابقة يمكنك الاستعانة بأى Resources طالما أنها Hard Copy, يمكنك أستخدام أى كتب أو أوراق مطبوعة, وتمنع اى Soft Copy Resources, وممنوع استخدام اى الة الكترونية (معدا الكمبيوتر طبعا) مثل الالة الحاسبة والموبايل وال Flash Memory ... الخ.

عادة ما يتم استخدام برنامج Eclipse ك Editor للكتابة الكود فى المسابقة.
 

فوائد المشاركة فى المسابقة:

المشاركة فى مسابقات ال ACM له فوائد كثيرة منها:
  • معرفة طرق جديدة للتفكير.
  • التدرب على Techniques جديدة للبرمجة.
  • تعلم Algorithms جديدة والتدريب عليها.
  • الاستمتاع بالبرمجة, فجو المسابقات ممتع.
  • روح المنافسة والتحدى بين الزملاء.
  • التعرف على مبرمجين من بلدك, وأحيانا من أنحاء العالم اذا شاركت فى المسابقات الاقليمية والعالمية.

نصائح للفريق:

  • فى البداية, اقرأوا جميع المسائل, يمكنكم تقسيمها.
  • ابدأ بحل المسألة السهلة فالأصعب.
  • أكتب كود المسألة كاملا فى ورقة قبل البدأ فى الكتابة على الكمبيوتر, حتى لا تستغرق وقت فى التفكير أثناء استخدام الكمبيوتر, لأن الكمبيوتر كما اتفقنا عامل مهم, وقد تتسبب فى تعطيل زميلك فى الفريق اذا اسأت استخدام الكمبيوتر.
  • لا تفقد أعصابك, وتذكر "انها مجرد لعبة".

هنا نسخة PDF من المقال.


    يعتبر برنامج PC^2 أهم ما فى مسابقات ال ACM, وذلك لأن عن طريقه يمكن أدارة المسابقة من كافة النواحى, ويعتبر قناة الوصل الوحيدة بين المتسابقين "Teams" والحكّام "Judges".

    وفى هذا الموضوع سنتناول الاتى :
    • كيفية الدخول الى البرنامج.
    • ارسال الحلول "Submit".
    • نتائج الحلول "Run Results".
    • التوضيحات والأسألة "clarification".
    • تغير ال Password.
    • ال Score Board.



    كيفية الدخول الى البرنامج :


    1- ادخل على الجزء المخصص لل Teams من البرنامج.


    2- أكتب أسم ال Team وال Password, غالبا ما يكون اسم ال team هو "Team + Number", سيعطى لك ورقة بها اسم ال Team وال Password.



    ارسال الحلول"Submit" :



    1. تأكد من أسم فريقك, فى هذا المثال اسم الفريق "FCIS Champion".
    2. عداد تنازلى يحسب الوقت المتبقى من المسابقة, تأكد من أنك تتابعه جيدا, لأن فى تلك المسابقات الوقت من ذهب.
    3. Problem : أذا أردت أن ترسل حلّ لمسألة, أختار اسم المسألة من هنا.
    4. Language : اختار لغة البرمجة التى ترسل بها كود المسألة, اللغات المتاحة فى الغالب هى C, C++, Java.
    5. Main File : اختار ال File الذى يحتوى على كود المسألة.
    6. Test : قبل أن ترسل الكود تأكد من أنه يعمل ولا يحتوى على أى Compile Error, ولكن أحيانا هذه الخاصية لا تعمل فى بعض المسابقات.
    7. Submit : أرسل الكود الى ال Judge.
    بعد عمل Submit ستظهر لك رسالة تاكيدية, بها اسم ال Team, وأسم ال Problem, وPath ال File الذى يحتوى على الكود, ولغة البرمجة التى أرسلت بها الكود.


    تأكد أن كل البيانات صحيحة ثم Submit.

    بعد ارسال الحلّ ستصل لك رسالة تفيد بأنك قد أرسلت الكود ووصل الى ال Judge بصورة صحيحة.



    اذا لم تصلك هذه الرسالة, فتأكد من أن الكود قد تم ارساله من "Runs".


    اذا تم ارسال الكود فستجد اسم ال Problem , وستجد ال Status لها New, وهذا يعنى أنك أرسلت المسألة ولم يصلك حتى الأن رد اذا كانت المسألة صحيحة أم لا.

    قائمة Run ستجد بها نتائج كل الحلول التى أرسلتها أثناء المسابقة, وبها أيضا الوقت الذى أرسلتها به.


    نتائج الحلول"Run Results" :


    عندما ينتهى ال Judge من معرفة اذا كان الحل الذى أرسلته صحيح أم لا, بإدخال File به Input معيّن لكودك, ومقارنة ال Output الخارج من الكود الذى أرسلته, بال Output الصحيح, يرسل لك رسالة بها نتيجة الحلّ الذى أرسلته.

    "Yes" فقط هى الرسالة الوحيدة التى تعنى أن الكود الذى أرسلته صحيح.



    التوضيحات والأسألة "Clarification" :


    أثناء المسابقة, إذا أردت أن تستفسر عن أى شئ فى أى مسألة, أو أن تسأل سؤالا تقنيا, أو أى سؤال آخر, يمكنك أرسال Clarification الى ال Judges, وهم سوف يجيبوا على استفسارك.

    1- اختر Request Clar.


    2- اكتب سؤالك واختار اسم ال Problem إذا كان سؤالك حول مسألة معينة, أو اختار General اذا كان سؤالك عام.
    واذا تم الرد على سؤالك سيتم ارسال رسالة لك مثل رسالة ال Run Result.



    لأظهار أى Clarification أضغط View Clarification.




    تغير ال Password :


    اذا أردت تغير ال Password المستخدمة لدخول فريقك الى البرنامج يمكنك تغيرها من Settings.


    ولكن لا ننصح بهذه الخطوة, لأنها قد تتسبب فى بعض المشاكل اذا نسيت ال Password الجديد.



    ال Score Board :


    صفحة بها ملخص لنتائج الفرق المشتركة فى المسابقة, وتكون مرتبة حسب الأكثر حلاً, ثم الأقل وقتا, وهذه الصفحة تتجدد تلقائيا أول 4 ساعات من المسابقة, والساعة الخامسة والأخيرة تسمى "Freeze Hour", وفيها لا تتجدد ال Score Board.

    A, B, C, ..... , H ترمز الى أرقام المسائل, وبجوار كل فريق تجد عدد المسائل الذى قام بحلّها (Solved), والوقت الذى استغرقه فى حلّ كل المسائل (Time), وتحت كل مسألة يُكتب (عدد مرات ارسال الحلّ / الوقت الذى استغرقه فى الحلّ).



    يتم حساب الوقت لكل مسألة من بداية المسابقة, فمثلا فريق CSC06 قاموا بحلّ المسألة E بعد 84 دقيقة من بداية المسابقة, ثم C بعد 225 دقيقة من بداية المسابقة.

    فى حالة ارسال حلّ خاطئ مرة أو أكثر, وبعد ذلك مرة صحيحة, فأن وقت حلّ المسألة يضاف اليه Penalty Time ويكون 20 دقيقة زائدة عن كل Submission خاطئ, مثال على ذلك فرق CSC06 قاموا بارسال المسألة G مرة خاطئة والثانية صحيحة, وأرسلوا الحلّ الصحيح بعد 140 دقيقة من بداية المسابقة, يضاف عليهم 20 دقيقة Penalty, اذن الوقت المحتسب للمسألة 160 دقيقة.

    لاحظ أن الوقت الكلّى للTeam يضاف اليه فقط وقت المسائل التى حصل ال Team بها على Yes.

    ال Score Board مفيدة للغاية, يمكنك من خلالها معرفة المسائل التى قام بحلّها كل الفرق, وغالبا ما تكون المسائل الأكثر سهولة هى الأكثر حلاً.


    ملحوظة : هنا نسخة PDF من المقال.