A Hundred Squares!

Python 2, 166 bytes

R=range;n=input()
for y in R(21):print''.join('♥[%dm%s♥[m'%(any(5>x-k%10*4>-1<y-k/10*2<3for k in R(n-1,100,n))*41,('+---|%2d '%(x/4+y*5-4))[y%2*4+x%4])for x in R(41))

Replace by octal 033 (the ANSI escape character).

enter image description here

Explanation

We treat the output as a 41×21 grid, and directly compute the character and color at each point.

That is, the structure of the code is:

n = input()
for y in range(21):
    print ''.join(F(x, y) for x in range(41))

for some function F.

The result of F is always of the following form:

  • An ANSI Control Sequence Introducer (\33[).
  • An SGR code: 0m for reset, or 41m for red background.
  • A single character. (+, -, |, space, or digit)
  • An SGR reset sequence (\33[m).

We use the format string '\33[%dm%s\33[m', where the first %d is either 0 or 41, and the %s is the character we wish to print.


For the color, we have the following formula:

any(5>x-k%10*4>-1<y-k/10*2<3for k in R(n-1,100,n))*41

I’m not going to fully explain this, but it basically loops over all rectangles that should be colored red, and checks if (x, y) is inside any of them.

Note the use of operator chaining: I rewrote -1<A<5 and -1<B<3 into 5>A>-1<B<3.


For the character, we have the following formula:

('+---|%2d '%(x/4+y*5-4))[y%2*4+x%4]

If y % 2 == 0 then for x = 0, 1, … this will generate +---+---+---…

If y % 2 == 1 then for x = 0, 1, … this will generate | p |p+1|p+2…


Julia, 219 182 169 167 bytes

!n=(~j=j%n<1;k(v=j->"---",c=+,s="$c\e[m";l=~)=println([(l(j)?"\e[;;41m$c":s)v(j)for j=10i+(1:10)]...,s);i=0;k();for i=0:9 k(j->lpad(j,3),|);k(l=j->~j|~(j+10(i<9)))end)

Used like this: !7

Ungolfed:

function !(n::Integer)
     for j=(1:10)     #This loop generates the top of the box
       if (j%n==0)
         print("\e[;;41m+---") #"\e[;;41m" is the ANSI escape code
                               #for red background colour in Julia
       else
         print("+\e[m---")     #"\e[m" resets to original colours
       end
     end
     println("+\e[m")
     for i=0:9
       for j=10i+(1:10)  #This loop generates the rows with the numbers
         if (j%n==0)
           print("\e[;;41m|",lpad(j,3))
         else
           print("|\e[m",lpad(j,3))
         end
       end
       println("|\e[m")
       for j=10i+(1:10)  #This loop generates the other rows
         if (j%n==0)||((j+10)%n==0&&i<9)
           print("\e[;;41m+---")
         else
           print("+\e[m---")
         end
       end
       println("+\e[m")
     end
   end

Note that this is very ungolfed, for maximal readability.