ADAPRIME spoj tle

时间:2017-12-26 13:14:14

标签: java algorithm math permutation primes

  

PROBLEM。这是SPOJ问题部分的一个问题。

     

正如您可能已经知道的,Ada the Ladybug是一位农民。她种了很多蔬菜和树木,她想区分它们。为此,她买了一个有趣的标志,里面有几个数字。标志上的数字可以任意置换(但不添加/删除)。 Ada喜欢素数所以她希望这些标志是素数(显然是不同的)。 您能找到可以获得素数的符号数吗?

注意:数字不能为前导零!

输入
The first line of input will contain 1 ≤ T ≤ 10000, the number of test-cases.

The next T lines will contain 1 ≤ D ≤ 9, the number of digits on sign, followed by D digits 0 ≤ di ≤ 9

输出
For each test-case, output the number of distinct primes which could be generated on given sign.

示例输入
5
1 9
3 1 2 3
5 1 2 0 8 9
7 1 0 6 5 7 8 2
5 1 2 7 3 1

示例输出
0
0
11个
283个
15

APPROACH

  

对于每个输入,我首先找到所有素数到9999999999.对于每个测试用例,我首先对最大大小为9的数组进行排序。排序后,我迭代地找到下一个排列,并检查它是否为素数或者不是(我已经做过,所以现在需要一段时间)。但我得到了TLE。我不知道在哪里可以优化我的代码。

代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;

public class Main
{
    public static int maxSize = (int)Math.pow(10,9);
    public static boolean[] isPrime = new boolean[maxSize];
    public static int count = 0;
    public static void main(String[] args) throws IOException
    {
        //find all the primes till maxSize - 1
        preProcess();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());
        while(t > 0)
        {
            String[] strArr = br.readLine().split(" ");
            int n = Integer.parseInt(strArr[0]);
            int[] arr = new int[n];
            for(int i = 0 ; i < n ; i++)
            {
                arr[i] = Integer.parseInt(strArr[i + 1]);
            }
            count = 0;
            HashSet<Integer> set = new HashSet<>();
            func(arr,0,n,set);
            System.out.println(count);
            t--;
         } 

    }
    public static void func(int[] arr,int pos,int n,HashSet<Integer> set)
    {
        Arrays.sort(arr);
        while(true)
        {
            //ignoring the leading zeroes cases.
            if(arr[0] != 0)
            {
                //parses the int array and produces the number.
                int val = parseInt(arr, n);
                //System.out.println("val = " + val);
                if(isPrime[val] == true && set.contains(val) == false)
                {
                    //System.out.println(val);
                    count++;
                    set.add(val);
                }
            }
            int i = n - 2;
            while(i >= 0 && arr[i] >= arr[i + 1])
            {
                i--;
            }
            if(i < 0)
                return;
            //finds the next greater number than arr[i]
            int index = findJustGreater(arr, i + 1, n - 1, arr[i]);
            swap(i,index,arr);
            reverse(arr, i + 1, n - 1);

        }
    }
    public static int findJustGreater(int[] arr,int l, int r,int key)
    {
        int low = l;
        int high = r;
        while(low < high)
        {
            if(high == low + 1)
            {
                if(arr[high] > key)
                    return high;
                else
                    return low;
            } 
            int mid = (low + high) / 2;
            if(arr[mid] > key)
            {
                low = mid;
            }
            else
            {
                high = mid - 1;
            }
        }
        return low;
    }

    public static void reverse(int[] arr,int i,int j)
    {
        while(i < j)
        {
            swap(i, j, arr);
            i++;
            j--;
        }
    }


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


    public static int parseInt(int[] arr,int n)
    {
        int sum = 0;
        for(int i = 0 ; i < n ; i++)
        {
            sum  = sum * 10 + arr[i];
        }
        return sum;
    }

    public static void preProcess()
    {
        for(int i = 0 ; i < maxSize ; i++)
        {
            isPrime[i] = true;
        }
        for(int i = 4 ; i < maxSize ; i += 2)
            isPrime[i] = false;

        int o = (int)Math.sqrt(maxSize) + 1;
        for(int i = 2 ; i <= o ; i++)
        {
            if(isPrime[i] == true)
            {
                for(int j = i * i ; j < maxSize ; j += 2 * i )
                {
                    isPrime[j] = false;
                }
            }
        }
    }
}

感谢帮助

0 个答案:

没有答案