Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], skipTags: ["script","noscript","style","textarea","code"], processEscapes: true }});

問題文

文字列 $S$ が与えられる。$S$ のすべてのアナグラムのうち、回文になっているものの個数を求めよ。

文字列 $X$ が $Y$ のアナグラムであるとは、$X$ が $Y$ と等しいか、$X$ の文字を並び替えたら $Y$ に等しくなることをいう。例えば文字列abcdに対して、abcdやcbdaなどはアナグラムであるが、abedやcabやabcddなどはアナグラムでない。

文字列 $X$ が回文であるとは、$X$ を逆から読んだものが $X$ 自身と等しくなることをいう。例えばabcやabは回文でなく、aやabccbaなどは回文である。

入力

入力は以下の形式に従う。

$S$

制約

$1 \leq |S| \leq 40$ ( $|S|$ は文字列 $S$ の長さ)

$S$ は小文字の英字のみを含む。

答は $2^{63}$ 未満であることが保証される。

出力

個数を1行に出力せよ。

Sample Input 1

ab

Output for the Sample Input 1

0

abのアナグラムはabとbaの二つがあるが、どちらも回文になっていない。

Sample Input 2

abba

Output for the Sample Input 2

2

abbaとbaabの二つの文字列が回文かつアナグラムになっている。

Solution in JAVA (judge verdict: Accepted)


import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		long ans = 1;
		int count[] = new int[26];
		int odd = 0;
		for(int i=0;i<s.length();i++){
			count[s.charAt(i)-'a']++;
			if(count[s.charAt(i)-'a']%2 == 1){
				odd++;
			}else{
				odd--;
			}
		}
		if(odd >= 2){
			System.out.println("0");
			return;
		}else{
			if(s.length() != 40){
				ans = fact((s.length()-odd)/2);
				for(int i=0;i<count.length;i++){
					if(count[i]%2 == 0){
						ans /= fact(count[i]/2);
					}else{
						ans /= fact((count[i]-1)/2);
					}
				}
			}else{
				double ansp = fact(19);

				for(int i=0;i<count.length;i++){
					if(count[i]%2 == 0){
						ansp /= fact(count[i]/2);
					}
				}

				ans = (long)ansp*20;
			}
		}
		System.out.println(ans);
	}

	static long fact(int n){
		if(n == 0)
			return 1;
		else
			return n * fact(n-1);
	}
}