ITES java로 풀려는데 입력 생성기 속도 관련 질문입니다.

  • yoonys427
    yoonys427

    문제에서 주어진 난수를 생성하기 위해 BigInteger를 사용했는데요
    아무래도 이 것 때문에 수행시간 초과가 나는 것 같아서요...
    BigInteger를 사용하지않고 입력 생성을 좀 더 빠르게 하는 방법이 있을까요?

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    import java.math.BigInteger;
    import java.util.Queue;
    import java.util.LinkedList;

    public class Main {

    static BigInteger mulNum = BigInteger.valueOf(214013);
    static BigInteger addNum = BigInteger.valueOf(2531011);
    static BigInteger modNum = BigInteger.valueOf((long) Math.pow(2, 32));
    static BigInteger makeIntNum = BigInteger.valueOf(10000);
    
    public static BigInteger makeNextBI(BigInteger previousBigNum) {
        return previousBigNum.multiply(mulNum).add(addNum).mod(modNum);
    }
    
    public static int makeCurrentInt(BigInteger current) {
        return current.mod(makeIntNum).intValue() + 1;
    }
    
    public static void popUntilK(Queue<Integer> queue, int[] countAndSum ,int k) {
        while(true) {
            if (countAndSum[1] == k) {
                countAndSum[0]++;
            }
    
            int temp = queue.poll();
            countAndSum[1] -= temp;
    
            if (countAndSum[1] < k) {
                return;
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
    
        int caseNum = Integer.parseInt(st.nextToken());
    
        for (int i = 0; i < caseNum; i++) {
    
            st = new StringTokenizer(br.readLine());
            int k = Integer.parseInt(st.nextToken());
            int n = Integer.parseInt(st.nextToken());
    
            int currentInt = 1983;
            BigInteger currentBigNum = BigInteger.valueOf(currentInt);
            currentInt = makeCurrentInt(currentBigNum);
            Queue queue = new LinkedList();
    
            int[] countAndSum = new int[2];
            countAndSum[0] = 0;
            countAndSum[1] = 0;
    
            for (int j = 0; j < n; j++) {
                queue.add(currentInt);
                countAndSum[1] += currentInt;
                currentBigNum = makeNextBI(currentBigNum);
                currentInt = makeCurrentInt(currentBigNum);
    
                if (countAndSum[1] >= k) {
                    popUntilK(queue, countAndSum, k);
                }
            }
            System.out.println(countAndSum[0]);
        }
    }

    }


    7년 전
2개의 댓글이 있습니다.
  • Corea
    Corea

    난수 생성 시, 단순히 unsigned int를 사용하시고 A[i] = (A[i-1] * 214013 + 2531011) 를 계속 적용시키시면 됩니다.


    7년 전 link
  • Corea
    Corea

    unsigned int의 범위가 0이상 2^{32} - 1이하여서 작동합니다.


    7년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.