العمل على الحالات

مشاكل العمل على الحالات هي تلك التي يُوجد حلها عبر تقسيم المشكلة إلى حالات مختلفة، حل كل واحدة منها بشكل منفصل، ثم دمج النتائج.

ما هو العمل على الحالات؟

في العديد من المسائل قد تحاول كتابة صيغة واحدة أو حلقة واحدة تغطي كل شيء. في مسائل العمل على الحالات، تلاحظ أن المواقف المختلفة تتصرف بشكل مختلف. لذا بدلًا من قاعدة واحدة عامة، تقول:

  • إذا حدثت الحالة A، افعل هذا.
  • إذا حدثت الحالة B، افعل ذاك.
  • وربما أيضًا الحالة C، الحالة D، إلخ.

ثم إما تجمع إجابات كل الحالات، أو تختار الأفضل بينها.

لماذا نستخدم العمل على الحالات؟

  • يسمح لك بالتعامل مع الحالات الخاصة بوضوح (عندما لا تكفي المنطقية البسيطة).
  • يساعدك في تقسيم مشكلة صعبة إلى أجزاء سهلة التعامل.
  • يظهر كثيرًا في مسائل العد أو المسائل ذات النتائج المتعددة.

كيف نقوم بالعمل على الحالات

  1. اقرأ المشكلة بعناية وابحث عن الأماكن التي يحدث فيها تغيير (مثل صغير/كبير، موجب/سالب، زوجي/فردي).
  2. حدد جميع الحالات المختلفة التي تغطي كل الاحتمالات دون تداخل.
  3. لكل حالة، اكتشف كيف تحسب النتيجة.
  4. اجمع النتائج إن لزم الأمر (إما جمعها أو أخذ الأصغر/الأكبر).
  5. تأكد أنك لم تفوّت أي حالة أو تحسب شيئًا مرتين.

أمثلة مسائل

Even or odd sum

Even or odd sum

لديك عددان \(a\) و \(b\). احسب عدد الأزواج \((i, j)\) بحيث \(1 \leq i \leq a\) و \(1 \leq j \leq b\) ويكون \(i + j\) زوجيًا.

Solution

ملاحظة: يكون \(i + j\) زوجيًا إذا كان كلاهما زوجيًا أو كلاهما فرديًا.

إذًا هناك حالتان:

  • الحالة 1: \(i\) زوجي و \(j\) زوجي
  • الحالة 2: \(i\) فردي و \(j\) فردي

احسب كل حالة واجمعهما معًا.

#include <iostream>
using namespace std;

int main() {
    int a, b;
    cin >> a >> b;

    int evenA = a / 2;
    int oddA = a - evenA;
    int evenB = b / 2;
    int oddB = b - evenB;

    int pairs = evenA * evenB + oddA * oddB;
    cout << pairs;
}

Triangle validity

Triangle validity

معطى لك ثلاثة أطوال أضلاع \(a, b, c\)، حدّد إن كانت تستطيع تشكيل مثلث.

Solution

يمكننا اختبار كل حالة عبر التحقق من أن مجموع أي ضلعين أكبر من الضلع الثالث

  • \(b + c > a\)
  • \(c + a > b\)
  • \(a + b > c\)

إذا كانت جميع هذه المتباينات صحيحة، فإن تكوين مثلث ممكن. سنقوم بالتحقق من كل واحدة من هذه المتباينات، وفي حال أي متباينة لم تتحقق، فالإجابة هي “no”، وإلا فالإجابة هي “yes”.

#include <iostream>
using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;

    bool ok = true;
    if (b + c <= a) ok = false;
    if (a + c <= b) ok = false;
    if (a + b <= c) ok = false;

    cout << (ok ? "YES" : "NO");
}

هذا يفحص كل حالة بشكل مستقل — مثال مباشر على العمل على الحالات.

Coordinate quadrant

Coordinate quadrant

معطى \((x, y)\)، اطبع أي ربع ينتمي إليه النقطة.

Solution

الحالات:

  • \(x > 0, y > 0\) ← Quadrant I
  • \(x < 0, y > 0\) ← Quadrant II
  • \(x < 0, y < 0\) ← Quadrant III
  • \(x > 0, y < 0\) ← Quadrant IV
  • إذا كان \(x = 0\) أو \(y = 0\) ← على المحور
#include <iostream>
using namespace std;

int main() {
    int x, y;
    cin >> x >> y;

    if (x > 0 && y > 0) cout << "Quadrant I";
    else if (x < 0 && y > 0) cout << "Quadrant II";
    else if (x < 0 && y < 0) cout << "Quadrant III";
    else if (x > 0 && y < 0) cout << "Quadrant IV";
    else cout << "On an axis";
}

نصائح للعمل على الحالات

  • تأكد أن حالاتك لا تتداخل.
  • تأكد أن كل الاحتمالات مغطاة.
  • انتبه للحدود (مثل 0 أو المساواة).
  • حافظ على المنطق واضحًا وبسيطًا.

خلاصة سريعة

  • العمل على الحالات يعني تقسيم المشكلة إلى مواقف أبسط.
  • حل كل حالة مستقلًا ثم دمج النتائج.
  • هو أسلوب تفكير، ليس خوارزمية خاصة.
  • ممتاز لمراحل البداية في حل المشاكل.

نصيحة: عندما تكون غير متأكد من البداية، فكر: “ما هي الحالات الممكنة؟” — هذه بداية العمل على الحالات.