给出 n 个字符串,对于每个 n 个排列 p,按排列给出的顺序(p[0] , p[1] … p[n-1])依次连接这 n 个字符串都能得到一个长度为这些字符串长度之和的字符串。所以按照这个方法一共可以生成 n! 个字符串。
一个字符串的权值等于把这个字符串循环左移 i 次后得到的字符串仍和原字符串全等的数量,i 的取值为 [1 , 字符串长度]。求这些字符串最后生成的 n! 个字符串中权值为 K 的有多少个。
注:定义把一个串循环左移 1 次等价于把这个串的第一个字符移动到最后一个字符的后面。
输入描述:
每组测试用例仅包含一组数据,每组数据第一行为两个正整数 n, K , n 的大小不超过 8 , K 不超过 200。接下来有 n 行,每行一个长度不超过 20 且仅包含大写字母的字符串。
输出描述:
输出一个整数代表权值为 K 的字符串数量。
输入例子:
3 2
AB
RAAB
RA
输出例子:
3
import java.util.Scanner;
public class Main {
private static int num;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
num = 0;
int n = scan.nextInt();
int k = scan.nextInt();
String[] strs = new String[n];
for (int i = 0; i < n; i++) {
strs[i] = scan.next();
}
permutation(strs, 0, strs.length - 1, k);
System.out.println(num);
}
scan.close();
}
/**
* 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理.
*
* @param strs
* @param start
* @param end
*/
private static void permutation(String[] strs, int start, int end,int k) {
if (start == end) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= end; i++) {
sb.append(strs[i]);
}
sovle(sb.toString(),k);
return;
}
for (int i = start; i <= end; i++) {
if (i != start){
swap(strs, i, start);
}
permutation(strs, start + 1, end,k);//固定好当前一位,继续排列后面的
if (i != start){
swap(strs, i, start);
}
}
}
private static void sovle(String str, int k) {
int count = 0;
String s = str + str;
for (int i = 1, len = str.length(); i <= len; i++) {
if (str.equals(s.substring(i,i+len))) {
++count;
}
}
if (count == k) {
++num;
}
}
private static void swap(String[] strs, int i, int start) {
String temp = strs[start];
strs[start] = strs[i];
strs[i] = temp;
}
}