首页 > 试题广场 >

魔法权值

[编程题]魔法权值
  • 热度指数:3154 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

给出 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 的字符串数量。

示例1

输入

3 2
AB
RAAB
RA

输出

3
// 复杂度太高了?没过。。不过应该是对的
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * Created by Gdeer on 2016-9-8.
 */
public class Main3 {

    private static ArrayList<String> list = new ArrayList<>();
    private static ArrayList<Integer> resultList = new ArrayList<>();

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n,k;

        while (scanner.hasNext()){
            list = new ArrayList<>();
            resultList = new ArrayList<>();
            n = scanner.nextInt();
            k = scanner.nextInt();

            for (int i = 0; i < n; i++) {
                String str = scanner.next();
                list.add(str);
            }

            int[] indexs = new int[list.size()];
            for (int i = 0; i < indexs.length; i++) {
                indexs[i] = i;
            }
            arrange(indexs, 0);

            int m = 0;
            for (int i : resultList) {
                if (i == k){
                    m++;
                }
            }
            System.out.println(m);
        }
    }

    private static void arrange(int[] array, int a) {
        int n = array.length;
        if (a == n - 1) {
            String s = createStr(array, list);
            resultList.add(getCount(s));
        } else {
            for (int i = 0; i < n - a; i++) {
                swap(array, a, a + i);
                arrange(array, a + 1);
                swap(array, a, a + i);
            }
        }
    }

    private static String createStr(int[] array, List list) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            sb.append(list.get(array[i]));
        }
        return sb.toString();
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    private static int getCount(String str) {
        int count = 1;
        for (int i = 0; i < str.length(); i++) {
            StringBuilder sb = new StringBuilder();
            String subStr = str.substring(0, i + 1);
            for (int j = 0; j < str.length() / subStr.length(); j++) {
                sb.append(subStr);
            }
            if (sb.toString().equals(str)) {
                count = str.length() / subStr.length();
                break;
            }
        }
        return count;
    }
}

编辑于 2016-09-08 17:54:13 回复(0)
递归生成全排列,判断权值,也就是串能分出多少个相同的子串,用KMP可解,
判断n-next[n]能否整除n,可以知道串是否由多个相同字串组成,
除完的商就是权值,不能整除的串权值为1.
import java.util.*; public class Main{ static ArrayList<String> res; public static int next(String arr){ int[] next=new int[arr.length()+1]; int res=1; next[0]=next[1]=0; int j=0; for(int i=1;i<arr.length();i++){ while(j>0&&arr.charAt(i)!=arr.charAt(j)) j=next[j]; if(arr.charAt(i)==arr.charAt(j)) { j++; } next[i+1]=j; } if(arr.length()%(arr.length()-next[arr.length()])==0) res=arr.length()/(arr.length()-next[arr.length()]); return res; } public static void allString(String[] strr,int s,int n){ String tmp; if(s==(n-1)){ tmp=""; for(int i=0;i<n;i++){ tmp+=strr[i]; } res.add(tmp); } for(int i=s;i<n;i++){ tmp=strr[s]; strr[s]=strr[i]; strr[i]=tmp; allString(strr,s+1,n); tmp=strr[s]; strr[s]=strr[i]; strr[i]=tmp; } } public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n,k,count; String[] strr; while(sc.hasNext()){ res=new ArrayList<String>(); count=0; n=sc.nextInt(); k=sc.nextInt(); strr=new String[n]; for(int i=0;i<n;i++){ strr[i]=sc.next(); } allString(strr,0,n); for(int i=0;i<res.size();i++){ if(next(res.get(i))==k) count++; } System.out.println(count); } sc.close(); } }

编辑于 2016-09-03 17:56:59 回复(2)