Problem:
Score : 600 points

Problem Statement

There is a game that involves three variables, denoted A, B, and C.

As the game progresses, there will be N events where you are asked to make a choice.
Each of these choices is represented by a string s_i. If s_i is AB, you must add 1 to A or B then subtract 1 from the other; if s_i is AC, you must add 1 to A or C then subtract 1 from the other; if s_i is BC, you must add 1 to B or C then subtract 1 from the other.

After each choice, none of A, B, and C should be negative.

Determine whether it is possible to make N choices under this condition. If it is possible, also give one such way to make the choices.

Constraints

1 \leq N \leq 10^5

0 \leq A,B,C \leq 10^9

N, A, B, C are integers.

s_i is AB, AC, or BC.

Input

Input is given from Standard Input in the following format:

N A B C
s_1
s_2
:
s_N

Output

If it is possible to make N choices under the condition, print Yes; otherwise, print No.

Also, in the former case, show one such way to make the choices in the subsequent N lines. The (i+1)-th line should contain the name of the variable (A, B, or C) to which you add 1 in the i-th choice.

Sample Input 1

2 1 3 0
AB
AC

Sample Output 1

Yes
A
C

You can successfully make two choices, as follows:

In the first choice, add 1 to A and subtract 1 from B. A becomes 2, and B becomes 2.

In the second choice, add 1 to C and subtract 1 from A. C becomes 1, and A becomes 1.

Sample Input 2

3 1 0 0
AB
BC
AB

Sample Output 2

No

Sample Input 3

1 0 9 0
AC

Sample Output 3

No

Sample Input 4

8 6 9 1
AC
BC
AB
BC
AC
BC
AB
AB

Sample Output 4

Yes
C
B
B
C
C
B
A
A

Solution in Go (1.14.1) (judge verdict: Wrong Answer)

package main

import (
	"strings"
	"strconv"
	"bufio"
	"fmt"
	"os"
)

var (
	list []string
	al   []int
	bl   []int
	cl   []int
	leng int 
)

func getStdin() []string {
	stdin := bufio.NewScanner(os.Stdin)
	lines := []string{}
	for stdin.Scan() {
		if err := stdin.Err(); err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
		lines = append(lines, stdin.Text())
	}
	//	readLine()
	return lines
}
func main() {
	//fmt.Printf("%c", 'a')
	//return 
	  l:= getStdin()
   l1:= strings.Split(l[0]," ")
   leng,_ = strconv.Atoi(l1[0])
	a,_:=  strconv.Atoi(l1[1])
	b,_:=  strconv.Atoi(l1[2])
	c,_:=  strconv.Atoi(l1[3])
	  list= l[1:]

	  al= make([]int,leng)
	  bl= make([]int,leng)

	  cl= make([]int,leng)
	  
for i:= leng-1; i>= 0 ; i-- {
	if i != leng-1 {

	al[i] = al[i+1] 
	bl[i] = bl[i+1] 

	cl[i] = cl[i+1] 
	}
	
	switch list[i] {
	case "AB":
		if i == leng-1 {
			al[i] =  1
			bl[i] = 1
			
		}else{
		al[i] = al[i+1] + 1
		bl[i] = bl[i+1] + 1
		}
	case "AC":
		if i == leng-1 {
			al[i] =  1
			cl[i] = 1
			
			}else{
		al[i] = al[i+1] + 1
		cl[i] = cl[i+1] + 1
		
			}
	case "BC":
		if i == leng-1 {
			bl[i] =  1
			cl[i] = 1
			
			}else{
		bl[i] = bl[i+1] + 1
		cl[i] = cl[i+1] + 1
		
			}
	}
}


	  r,r1:=  calc(a,b,c, 0,list)
	  if( r1 == -1){
		fmt.Println("No")
		return 
	  }
	  fmt.Println("Yes")
dump(r)
}

func dump ( b []byte){

for i:= 0; i< len(b) ; i++{
	fmt.Printf("%c\r\n", b[i])
}
}
func next(a, b, c int, idx int, list []string) (int, func() ([]byte, int)) {
	if ( a < 0 || b < 0 || c < 0){
		return -1, func() ([]byte, int){ return nil ,-1}
	}
	if idx== leng{
		ret := make([]byte, 0)
		return 1, func() ([]byte, int){ return ret ,1}
	}
	//var p11, p12, p21, p22 int
//	var p12, p21 int
	if al[idx] < a && bl[idx] < b && cl[idx] < c {

		ret := make([]byte, 0)
		for i:= idx; i< leng; i++{
			ret = append ( ret , list[i][0]) 
		}
		return 1, func() ([]byte, int){ return ret, 1}
	}

	if al[idx] < a+ 10 && bl[idx] < b+ 10 && cl[idx] < c+ 10 {

	/*	ret := make([]byte, 0)
		for i:= idx; i< leng; i++{
			ret = append ( ret , list[i][0]) 
		}*/
		return 2, func() ([]byte, int){ return calc( a,b,c,idx,list)}
	}
/*	switch list[idx] {
	case "AB":
		//	p11 = a + 1
		p12 = b - 1
		p21 = a - 1
	//	p22 = b + 1
	case "AC":
		//	p11 = a + 1
		p12 = c - 1
		p21 = a - 1
	//	p22 = c + 1

	case "BC":
		//	p11 = b + 1
		p12 = c - 1
		p21 = b - 1
	//	p22 = c + 1
	default:
		return -1, func() ([]byte, int){ return nil ,-1}
	}

	if p12 > 0 && p21 > 0 {
		return -1, func() ([]byte, int){ return nil ,-1}
	}
	*/

	return 0, func() ([]byte, int){ return calc( a,b,c,idx,list)}

}

func calc(a, b, c int, idx int, list []string) ([]byte, int) {
	
	if ( a < 0 || b < 0 || c < 0){
		return nil,-1
	}
	if idx== leng{
		ret := make([]byte, 0)
		return ret,1
	}
	var ret1, ret2 []byte
	var bb1, bb2 int
	var b1, b2 int
	var r1, r2 byte
	var f1, f2 func() ([]byte, int)
	switch list[idx] {
	case "AB":
		r1 = 'A'
		r2 = 'B'
		bb1, f1 = next(a+1, b-1, c, idx+1, list)
		bb2, f2 = next(a-1, b+1, c, idx+1, list)
	case "AC":
		r1 = 'A'
		r2 = 'C'
		bb1, f1 = next(a+1, b, c-1, idx+1, list)
		bb2, f2 = next(a-1, b, c+1, idx+1, list)

	case "BC":

		r1 = 'B'
		r2 = 'C'
		bb1, f1 = next(a, b+1, c-1, idx+1, list)
		bb2, f2 = next(a, b-1, c+1, idx+1, list)
	default:
		return nil, -2
	}
	if bb1 == -1 && bb2 == -1 {
		return nil, -1
	}

	if bb1 == 1 {
		ret1, b1 = f1()
		b2 = -1
	} else if bb2 == 1 {
		r1 = r2
		ret1, b1 = f2()
		b2 = -1
	} else if bb1 == 2{

		ret1, b1 = f1()
		if  b1 == -1{
		//b2 = -1
		ret2, b2 = f2()
		}
		//b2 = -1
	}else if bb2 == 2{

		ret2, b2 = f2()
		if  b2 == -1{
		//b2 = -1
		ret1, b1 = f1()
		}
		//b2 = -1
	}



	if b1 == -1 && b2 == -1 {

		return nil, -1
	}
	if b1 == 1 {
		ret := make([]byte, 1)

		ret[0] = r1
		return append(ret, ret1...), 1

	}

	ret := make([]byte, 1)

	ret[0] = r2
	return append(ret, ret2...), 1

}