Optimization is totally unnecessary for this.
This is an introductory C++ kind of assignment, which typically asks for a simple concept as code. Note that OP's requirements are simply:
• accept N as input
• find p ≤ N such that p is prime
• print p
This does not even require a function or any other control construct besides the ability to write a loop. A function is really, really helpful in terms of thinking through the assignment though.
Notice how the requirements
do not ask us to verify 2 ≤ N ≤ 10000. Rather, it is stated that the input will be within that range. Therefore: don't spend time checking that — it is not part of the assignment to do so.
Done!
The second point separates into two parts:
• p ≤ N suggests that we need a loop: if p==N is not prime, then check p==N1, then p==N2, etc until p is discovered to be prime.
• code to check whether p is prime.
We can write the loop part easily enough:
1 2 3 4 5

int p = N;
while (!prime( p ))
{
p = 1;
}
 
Again, notice how we don't care to check that N is a "safe" number. Input is expected to be in the range [2, 10000].
Now the hardest part: determining if a number is prime.
Question: is 25 prime?
 is it evenly divisible by 2? no
 is it evenly divisible by 3? no
 is it evenly divisible by 4? no
 is it evenly divisible by 5? YES
Answer: 25 is not prime.
Question: is 7 prime?
 is it evenly divisible by 2? no
 is it evenly divisible by 3? no
 is it evenly divisible by 4? no
 is it evenly divisible by 5? no
 is it evenly divisible by 6? no
 is it... oh, wait, 7 == 7. we're done.
Answer: 7 is prime.
Again, you should see how this suggests a loop. Start at two and check for even divisibility each time. If you get to the number you are testing then you have yourself a prime number. But if you find an evendivisor you have a composite number. This is where a function really helps:
1 2 3 4 5 6 7 8 9 10 11 12 13

bool prime( int p )
{
int n = 2;
while (n < p)
{
if (n evenly divides p)
{
return false; // not prime!
}
n += 1;
}
return true; // prime!
}
 
The check for even divisibility in C and C++ is using the "remainder" operator (often called the "modulo" or "modulus" operator), because it gives you the remainder of a division instead of the integer quotient:
p / n → integer quotient of p divided by n
p % n → remainder of p divided by n
If the remainder is zero, then you have an even divisor. (You can say that "n divides p".)
The last thing to do is to print your newlyfound prime number ≤ N:
Again, you do not have to care about checking bounds, etc. You know that your input is going to be valid, and all valid inputs satisfy finding a prime number.
C:\Users\twaynfme\cpp> assignment2
2
2
C:\Users\twaynfme\cpp> assignment2
3
3
C:\Users\twaynfme\cpp> assignment2
4
3
C:\Users\twaynfme\cpp> assignment2
5
5
C:\Users\twaynfme\cpp> assignment2
6
5
C:\Users\twaynfme\cpp> assignment2
25
23

Notice how it works. Given a prime number, you get back that same prime number. Given a composite number, you get the nextlargest prime number.
The algorithm here to find a prime number can be improved very slightly, but even if not, it is more than fast enough for any integer in [2, 10000].
You can write this without the function, of course, but in my opinion that would make it
more difficult to keep things straight in your head. The purpose of the function is to keep separate things separate: backward counting loop in main is a different thing than the loop to determine whether a number is prime or not. Keep the tasks separate in your head and life is simpler.
Hope this helps.