Help me please !


Give the range of integers. Find and print absolute values ​​of the two numbers with the least difference.
Input format: The first line is N - the number of integers in the list.
Next lines are N integers separated by spaces.

Constraint: 1 <N <100; Integers in segments [-10000, 10000]

Output format: The absolute value of the two numbers in the range is the smallest difference.


Input Description
3
22 1 33

4
1 -1 1 -1

7
-1 -2 -3 11 22 21 -5

Output Description
11

0

1
#include <iostream>
#include <cmath>
using namespace std;

int main(){
int n;
cin >> n;
int a[n];
for(int i = 0; i < n; i++){
cin >> a[i];
}
int min = abs(a[0] - a[1]);
for(int i = 0; i < n - 1; i++){
for(int j = i + 1; j < n; j++){
if( abs(a[i] - a[j] < min) )
min = abs( a[i] - a[j] );
}
}
cout << min;
}
20/100 rin oi :((((
(a) store the numbers in a std::vector<int>; (b) std::sort() the vector; (c) apply std::unique() to check if all numbers are uniqe, else 0 is our answer – http://en.cppreference.com/w/cpp/algorithm/unique; (d) in case all numbers are unique, since the vector is sorted now you only need to check absolute values of the difference of adjacent numbers
(a) store the numbers in a std::vector<int>; (b) std::sort() the vector; (c) apply std::unique()

...I'm madly in love with std::set... :-)
... std::set ...

will not work because std::set will not accept non-unique entries by default and give a false reading. Perhaps std::multiset: http://en.cppreference.com/w/cpp/container/multiset
I think I'd go with Enoizat's advice (choice of a set as a container that is ... not the romantic attachment to one!)

- it will do the sorting for you as you insert elements;
- you can stop reading any more integers if it finds any that are already in the set and you can immediately report 0 as the minimum difference
Last edited on
My proposal (ok, it was intended to be a play on words... Does it work in English?):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Give the range of integers. Find and print absolute values of the two 
// numbers with the least difference.
// Input format: The first line is N - the number of integers in the list.
// Next lines are N integers separated by spaces.
// Constraint: 1 <N <100; Integers in segments [-10000, 10000]
// Output format: The absolute value of the two numbers in the range 
// is the smallest difference.
#include <cmath>
#include <iostream>
#include <iterator>
#include <limits>
#include <set>

bool isInRange(int value);
void waitForEnter();

int main()
{
    int howmany {};
    do {
        std::cout << "How many numbers do you want to evaluate (1-100)? ";
        std::cin >> howmany;
        std::cin.ignore(1);
        if(100 < howmany || howmany < 1) {
            std::cout << "Accepted value ranges from 1 to 100.\n";
        }
    } while(howmany < 1 || 100 < howmany);
    
    std::cout << "Please insert your numbers separated by spaces.\n"
                 "Numbers can range from -10000 to 10000.\n"
                 "> ";
    std::set<int> sequence;
    for(int i{}; i<howmany; i++) {
        int tmp;
        std::cin >> tmp;
        std::cin.ignore(1);
        if(!isInRange(tmp)) {
            std::cout << "Number out of range found: " << tmp
                      << "\nExiting program\n";
            return 1; // bad user input
        }
        if(!(sequence.insert(tmp)).second) {
            std::cout << "Duplicate found: " << tmp
                      << "\nTherefore smallest distance is 0\n";
            return 2; // duplicate number
        }
    }
    
    int distance {abs(-10000 - 10000) + 1};
    for(auto it{sequence.cbegin()}, it2{std::next(it)}; 
            it!=sequence.cend() && it2!=sequence.cend();
            it = it2++) {
        int tmp = abs(*it - *it2);
        if(distance > tmp) { distance = tmp; }
    }
    std::cout << "\nSmallest distance between your numbers is " << distance
              << '\n';
    
    waitForEnter();
    return 0;
}

bool isInRange(int value)
{ return (-10000 <= value && value <= 10000); }

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Last edited on
If they are known to be in ascending order then it should be possible to avoid using abs().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <fstream>
#include <set>
using namespace std;

int main()
{
   int N, val;
   set<int> a;
   
   ifstream in( "infile.dat" );
   in >> N;
   for ( int i = 0; i < N; i++ )
   {
      in >> val;
      if ( !a.insert( val ).second ) { cout << 0; return 0; }
   }
   
   auto p = a.begin(), q = p;
   q++;
   int minimum = *q - *p;
   while ( ++q != a.end() )
   {
      p++;
      int diff = *q - *p;
      if ( diff < minimum ) minimum = diff;
   }
   
   cout << minimum;
}

If they are known to be in ascending order then it should be possible to avoid using abs().

Very good (mathematical) point, @lastchance!
I’m adding it to my long list: “Bright solutions I couldn’t find because I’m not good at math”.
Topic archived. No new replies allowed.