Problem:
ABC Gene

文字列 ABC で表される遺伝子配列がある。あなたは次の操作を何回か行い、この遺伝子配列を書き換えていくことができる。

文字 A，B，C のうち 1 つを選ぶ。これを x とおく。遺伝子配列に含まれるすべての x をそれぞれ ABC へ同時に置き換える。

A，B，C だけからなる文字列 S が与えられる。遺伝子配列を S に一致させられるか判定せよ。

Constraints

1 ≤ |S| ≤ 5,000

S は A，B，C だけからなる。

Input Format

入力は以下の形式で標準入力から与えられる。

S

Output Format

遺伝子配列を S に一致させられるならば Yes を、一致させられないならば No を一行に出力せよ。

Sample Input 1

ABC

Sample Output 1

Yes

遺伝子配列ははじめから ABC である。

Sample Input 2

AABCC

Sample Output 2

Yes

B を選んで操作を行うと ABC → AABCC となる。

Sample Input 3

AABCABC

Sample Output 3

No

例えば、C を選んで操作を行っても AABCC → AABCABC とはならない。すべての C をそれぞれ ABC へ同時に置き換えるので、実際は AABCC → AABABCABC となる。

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using static System.Math;
using System.Numerics;
static class Program{
	const int mod=(int)1e9+7;
	static void Main(){
		Sc sc=new Sc();
		var s=sc.S;
		if(s.Length%2==0||s.Length==1||s[0]!='A'||s[s.Length-1]!='C'){
			Console.WriteLine("No");
			return;
		}
		var ll=new LinkedList<int>();
		var h=new int[4];
		int m=s.Length;
		ll.AddFirst(0);
		for(int i = 0;i<s.Length;i++) {
			if(s[i]=='A'){ll.AddLast(1);h[1]++;}
			else if(s[i]=='B'){ll.AddLast(2);h[2]++;}
			else {ll.AddLast(3);h[3]++;}
		}
		ll.AddLast(0);
		string ans="Yes";
		while(m>3){
			if(h[1]<1||h[2]<1||h[3]<1){ans="No";break;}
			var e=ll.First.Next;
			if(h[1]<h[2]&&h[1]<h[3]){
				m-=h[1]<<1;
				while(e.Value!=0){
					if(e.Value==1){
						if(e.Next.Value==2&&e.Next.Next.Value==3){
							ll.Remove(e.Next);
							ll.Remove(e.Next);
							h[2]--;
							h[3]--;
						}
						else{ans="No";break;}
					}
					e=e.Next;
				}
			}
			else if(h[2]<h[1]&&h[2]<h[3]){
				m-=h[2]<<1;
				while(e.Value!=0){
					if(e.Value==2){
						if(e.Previous.Value==1&&e.Next.Value==3){
							ll.Remove(e.Previous);
							ll.Remove(e.Next);
							h[1]--;
							h[3]--;
						}
						else{ans="No";break;}
					}
					e=e.Next;
				}
			}
			else{
				m-=h[3]<<1;
				while(e.Value!=0){
					if(e.Value==3){
						if(e.Previous.Value==2&&e.Previous.Previous.Value==1){
							ll.Remove(e.Previous);
							ll.Remove(e.Previous);
							h[1]--;
							h[2]--;
						}
						else{ans="No";break;}
					}
					e=e.Next;
				}
			}
		}
		if(m!=3||ll.First.Next.Value!=1||ll.First.Next.Next.Value!=2||ll.First.Next.Next.Next.Value!=3){ans="No";}
		Console.WriteLine("{0}",ans);
	}
}

public class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
	public object[] Oa{get{return Console.ReadLine().Split();}}
	public int[] Ia2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),int.Parse);}}
	public int[] Ia3(int a){return Array.ConvertAll((a.ToString()+" "+Console.ReadLine()).Split(),int.Parse);}
	public int[] Ia3(bool a,int b,bool c,int d){return Array.ConvertAll(((a?b.ToString()+" ":"")+Console.ReadLine()+(c?" "+d.ToString():"")).Split(),int.Parse);}
	public long[] La2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),long.Parse);}}
	public long[] La3(int a){return Array.ConvertAll((a.ToString()+" "+Console.ReadLine()).Split(),long.Parse);}
	public long[] La3(bool a,int b,bool c,int d){return Array.ConvertAll(((a?b.ToString()+" ":"")+Console.ReadLine()+(c?" "+d.ToString():"")).Split(),long.Parse);}
	public T[] Arr<T>(int n,Func<T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f();}return a;}
	public T[] Arr<T>(int n,Func<int,T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i);}return a;}
	public T[] Arr<T>(int n,Func<string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(Console.ReadLine().Split());}return a;}
	public T[] Arr<T>(int n,Func<int,string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i,Console.ReadLine().Split());}return a;}
}