Professional Documents
Culture Documents
02
SOLVE A CHALLENGING CODE PROBLEM
MAXIMUM PAIRWISE PRODUCT
IMRAN IHSAN
ASSISTANT PROFESSOR, AIR UNIVERSITY, ISLAMABAD
WWW.IMRANIHSAN.COM
max aiaj
0≤i≠j≤n−1
2
INPUT / OUTPUT
• Input
• The first line of the input contains an integer n.
• The next line contains n non-negative integers a0,…,an−1
(separated by spaces).
• Constraints
2 ≤ n ≤ 2⋅105;
0 ≤ a0,…,an−1 ≤ 105.
• Output
• Output a single number — the maximum pairwise product.
3
SAMPLE 1
• Input:
1. 3
2. 1 2 3
• Output:
1. 6
• Explanation:
6=2×3
4
SAMPLE 2
• Input:
1. 10
2. 7 5 14 2 8 8 10 1 2 3
• Output:
1. 140
• Explanation:
140 = 14 × 10
5
STARTER SOLUTION
1 #include <iostream>
2 #include <vector>
3
4 using std::vector;
5 using std::cin;
6 using std::cout;
7
8 int MaxPairwiseProduct(const vector<int>& numbers) {
9 int result = 0;
10 int n = numbers.size();
11 for (int i = 0; i < n; ++i) {
12 for (int j = i + 1; j < n; ++j) {
13 if (numbers[i] * numbers[j] > result) {
14 result = numbers[i] * numbers[j];
15 }
16 }
17 }
18 return result;
19 }
20
21 int main() {
22 int n;
23 cin >> n;
24 vector<int> numbers(n);
25 for (int i = 0; i < n; ++i) {
26 cin >> numbers[i]; }
27
28 int result = MaxPairwiseProduct(numbers);
29 cout << result << "\n";
30 return 0;
31 }
32
33
6
TEST THE SYSTEM
• Input:
1. 2
2. 100000 90000
• Output:
1. 410065408
• Explanation:
Correct Output: 9000000000
Failed Case: Wrong Answer
7
FIXING AN INTEGER OVERFLOW BUG
1 #include <iostream>
2 #include <vector>
3
4 using std::vector;
5 using std::cin;
6 using std::cout;
7
8 double MaxPairwiseProduct(const vector<int>& numbers) {
9 double result = 0;
10 int n = numbers.size();
11 for (int i = 0; i < n; ++i) {
12 for (int j = i + 1; j < n; ++j) {
13 if (((double)numbers[i]) * numbers[j] > result) {
14 result = ((double)numbers[i]) * numbers[j];
15 }
16 }
17 }
18 return result;
19 }
20
21 int main() {
22 int n;
23 cin >> n;
24 vector<int> numbers(n);
25 for (int i = 0; i < n; ++i) {
26 cin >> numbers[i]; }
27
28 double result = MaxPairwiseProduct(numbers);
29 cout << result << "\n";
30 return 0;
31 }
32
33
8
TEST AGAIN
• Input:
1. 2
2. 100000 90000
• Output:
1. 9000000000
• Explanation:
Correct Answer
9
HOWEVER SYSTEM FAILS AGAIN
TIME LIMIT EXCEEDED
10
IMPLEMENTING A FASTER SOLUTION
1 double MaxPairwiseProductFast(const vector<int>& numbers) {
2 int n = numbers.size();
3 int max_index1 = -1;
4 for (int i = 0; i < n; ++i)
5 if ((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
6 max_index1 = i;
7
8 int max_index2 = -1;
9 for (int j = 0; j < n; ++j)
10 if ((numbers[j] != numbers[max_index1]) &&
11 ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
12 max_index2 = j;
13
14 return ((double)(numbers[max_index1])) * numbers[max_index2];
15 }
16
17 int main() {
18 int n;
19 cin >> n;
20 vector<int> numbers(n);
21 for (int i = 0; i < n; ++i) {
22 cin >> numbers[i];
23 }
24
25 double result1 = MaxPairwiseProduct(numbers);
26 double result2 = MaxPairwiseProductFast(numbers);
27
28 cout << result1 << "\n" << result2;
29 return 0;
30 }
31
32
33
11
TESTING
• Input:
1. 3
2. 7 2 5
• Output:
1. 35
2. 35
• Explanation:
Satisfactory
12
STRESS TEST
1 while (true) {
2 int n = rand() % 10 + 2;
3 cerr << n << "\n";
4
5 vector<int> a;
6 for (int i = 0; i < n; ++i) {
7 a.push_back(rand() % 100000);
8 }
9
10 for (int i = 0; i < n; ++i) {
11 cerr << a[i] << ' ';
12 }
13 cerr << "\n";
14
15 double res1 = MaxPairwiseProduct(a);
16 double res2 = MaxPairwiseProductFast(a);
17
18 if (res1 != res2) {
19 cerr << "Wrong answer: " << res1 << ' ' << res2 << "\n";
20 break;
21 }
22 else {
23 cerr << "OK\n";
24 }
25 }
26
27
28
29
30
31
32
33
13
RUN STRESS TEST
1 ...
2 OK
3
4 3
5 67232 68874 69499
6 OK
7
8 8
9 6132 56210 45236 95361 68380 16906 80495 95298
10 OK
11
12 11
13 62180 1856 89047 36823 14251 8362 34171 93584 87362 83341 8784
14 OK
15
16 6
17 21468 16859 82178 70496 82939 44491
18 OK
19
20 11
21 68165 30342 87637 74297 2904 32873 86010 87637 66131 82858 82935
22 Wrong answer: 7680243769 7537658370
23
24
25
26
27
28
29
30
31
32
33
14
STRESS TEST – SMALL & SIMPLE INPUT
1 while (true) {
2 int n = rand() % 4 + 2;
3 cerr << n << "\n";
4
5 vector<int> a;
6 for (int i = 0; i < n; ++i) {
7 a.push_back(rand() % 10);
8 }
9
10 for (int i = 0; i < n; ++i) {
11 cerr << a[i] << ' ';
12 }
13 cerr << "\n";
14
15 double res1 = MaxPairwiseProduct(a);
16 double res2 = MaxPairwiseProductFast(a);
17
18 if (res1 != res2) {
19 cerr << "Wrong answer: " << res1 << ' ' << res2 << "\n";
20 break;
21 }
22 else {
23 cerr << "OK\n";
24 }
25 }
26
27
28
29
30
31
32
33
15
A FASTER SOLUTION
1 double MaxPairwiseProductFast(const vector<int>& numbers) {
2 int n = numbers.size();
3 int max_index1 = -1;
4 for (int i = 0; i < n; ++i)
5 if ((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
6 max_index1 = i;
7
8 int max_index2 = -1;
9 for (int j = 0; j < n; ++j)
10 if ((numbers[j] != numbers[max_index1]) &&
11 ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
12 max_index2 = j;
13
14 cout << max_index1 << ‘ ‘ << max_index2 << “\n”;
15
16 return ((double)(numbers[max_index1])) * numbers[max_index2];
17 }
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
16
FINDING A SMALL AND SIMPLE TEST CASE
1 ...
2 3
3 7 3 6
4 0 2
5 OK
6
7 5
8 2 9 3 1 9
9 1 2
10 Wrong answer: 81 27
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
17
A FASTER SOLUTION – CORRECT ANSWER
1 double MaxPairwiseProductFast(const vector<int>& numbers) {
2 int n = numbers.size();
3 int max_index1 = -1;
4 for (int i = 0; i < n; ++i)
5 if ((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
6 max_index1 = i;
7
8 int max_index2 = -1;
9 for (int j = 0; j < n; ++j)
10 if ((j != max_index1) && ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
11 max_index2 = j;
12
13 return ((double)(numbers[max_index1])) * numbers[max_index2];
14 }
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
18