الثلاثي المثالي
الزمن المحدد: 1 ثانية
الذاكرة المحددة: 256 ميجابايت
يلعب ثلاثة أصدقاء لعبة تنسيق اسمها «الثلاثي المثالي».
أُعطوا قائمة مشاهير؛ لدى المشهور رقم \(i\) بالضبط \(A_i\) متابعًا. للفوز يجب اختيار ثلاثة مشاهير مختلفين بالضبط، بحيث يساوي مجموع أعداد متابعيهم \(S\).
حدد هل يوجد هذا الثلاثي. إذا وُجد فاطبع أي ثلاث قيم صحيحة، وإلا فاطبع \(-1\).
المدخلات
يحتوي السطر الأول على \(N\) و\(S\)، عدد المشاهير والمجموع المطلوب. ويحتوي السطر الثاني على \(N\) عددًا \(A_1,A_2,\ldots,A_N\).
مضمون أن \(3 \le N \le 10000\) و\(0 \le A_i,S \le 7\cdot10^8\).
المخرجات
إذا وُجد ثلاثة مشاهير مختلفون مجموع متابعيهم \(S\)، فاطبع أي ثلاث قيم منهم. وإلا فاطبع \(-1\).
التقييم
| المهمة الفرعية | القيود الإضافية | النقاط |
|---|---|---|
| \(1\) | \(N=3\) | \(7\) |
| \(2\) | \(N=4\) | \(8\) |
| \(3\) | \(N=5\) | \(9\) |
| \(4\) | \(N\le100\) | \(26\) |
| \(5\) | \(N\le10000, S\le100000\) | \(31\) |
| \(6\) | \(N\le10000, S\le7\cdot10^8\) | \(19\) |
أمثلة
المدخلات
3 6
1 2 3
المخرجات
1 2 3
المدخلات
6 1000
182 587 952 374 39 741
المخرجات
39 374 587
ملاحظات
في المثال، القيم الثلاث المختارة لأعداد المتابعين هي \(374\) و\(39\) و\(587\)، ومجموعها:
\[374 + 39 + 587 = 1000\]
لاحظ أن:
- المشاهير الثلاثة المختارون يجب أن يكونوا مختلفين؛
- إذا وُجدت عدة إجابات صحيحة، فيمكنك طباعة أي واحدة منها؛
- يمكن طباعة القيم بأي ترتيب.
الحل
رتّب أعداد المتابعين. ثبّت المشهور الأول عند الموضع \(i\)، ثم استخدم مؤشرين للبحث عن قيمتين لاحقتين مجموعهما \(S-A_i\). حرّك المؤشر الأيسر يمينًا إذا كان المجموع أصغر من المطلوب، والأيمن يسارًا إذا كان أكبر. المواضع الثلاثة مختلفة دائمًا حتى لو تساوت بعض القيم. التعقيد \(O(N^2)\) زمنيًا و\(O(1)\) ذاكرة إضافية عدا المصفوفة المرتبة.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
long long target;
cin >> n >> target;
vector<long long> a(n);
for (long long& value : a) {
cin >> value;
}
sort(a.begin(), a.end());
for (int i = 0; i < n - 2; i++) {
int left = i + 1;
int right = n - 1;
while (left < right) {
long long sum = a[i] + a[left] + a[right];
if (sum == target) {
cout << a[i] << ' ' << a[left] << ' ' << a[right] << '\n';
return 0;
}
if (sum < target) {
left++;
} else {
right--;
}
}
}
cout << -1 << '\n';
}