Python, 562 characters, -8 with ugly output, +4? for bash invocation 
=

 I=int;R=range
 import sys;a=sys.argv
 S=I(a[1]);f=[[0]*(S+2)for _ in R(S+2)]
 C=a[2].split()
 X=[]
 for i,n in enumerate(C):X=[i+1]*I(n)+X
 Q=a[3].split()
 for q in Q:f[I(q[1:])][ord(q[0])-64]=1
 D=R(-1,2)
 V=lambda r,c:(all(f[r+Q][c+W]<2for Q in D for W in D),0,0)[f[r][c]]
 def F(X):
 if not X:print"\n".join(" ".join(" .@"[c]for c in r[1:-1])for r in f[1:-1])
 x=X[0];A=R(1,S+1)
 for r in A:
 	for c in A:
 	 for h in(0,1):
 		def P(m):
 		 for i in R(x):f[(r+i,r)[h]][(c,c+i)[h]]=m
 		if(r+x,c+x)[h]<S+2and all(V((r+i,r)[h],(c,c+i)[h])for i in R(x)):P(2);F(X[1:]);P(0)
 F(X)

Note: the indent levels are space, tab, tab + space, tab + tab, and tab + tab + space. This saves a few characters from using spaces only.

**Usage and example**:

Takes input from command line arguments. Outputs a blank as a space, a shot as a `.`, and a `@` as part of a ship:

 $ python bships_golf.py "7" "4 0 2 0 1" \
 "A1 C3 B5 E4 G6 G7 A3 A4 A5 A6 C1 C3 C5 C7 B6 B7 D1 D2 G3" 2>X
 . @ . . @ @ @
 @ .
 . @ . @ @ .
 . @ .
 . . . @ @
 . . @ .
 @ . . @ @ .

When unsolvable, prints nothing:

 $ python bships_golf.py "3" "2" "A1 A3 B1 C1 C3" 2>X
 . . .
 @ @
 . .
 $ python bships_golf.py "3" "2" "A1 A2 A3 B1 C1 C3" 2>X
 $

The ` 2>X` is to suppress an error message since the program exits by throwing an exception. Feel free to add a +4 penalty if deemed fair. Otherwise I'd have to do a `try: ... except:0` to suppress it, which would take more characters anyway.

I can also print the output as numbers (`0`, `1`, and `2`) to shave off 8 characters, but I value aesthetics. 

**Explanation**:

I represent the board as a list of lists of integers with size 2 greater than the input, to avoid having to do bounds checking. `0` represents an empty space, `1` a shot, and `2` a ship. I run through the shots list `Q` and mark all the shots. I convert the list of ships to an explicit list `X` of ships, e.g. `[4, 0, 2, 0, 1]` becomes `[5, 3, 3, 1, 1, 1, 1]`. Then it's a simple backtracking algorithm: in order of descending size order, try to place a ship, and then try to place the rest of the ships. If it doesn't work, try the next slot. As soon as it succeeds, the ship list `X` is null, and accessing `X[0]` throws an exception which quits the program. The rest is just heavy golfing (was initially 1615 characters).