www.acmicpc.net/problem/1016

 

1016번: 제곱 ㄴㄴ 수

첫째 줄에 min과 max가 주어진다. min은 1보다 크거나 같고, 1,000,000,000,000보다 작거나 같은 자연수이고, max는 min보다 크거나 같고, min+1,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net


  • 숫자의 범위가 1조까지 가기 때문에, 적절한 자료형을 선택한다.
  • 에라토스테네스의 체를 이용해 제곱수의 배수들을 걸러준다.
  • 그렇다고 1조까지의 모든 값들에 대한 배열을 만들수도 없고, 반복문을 전부 돌릴수도 없기 때문에, 최솟값과 최댓값 사이의 값들에 대해서만 검사를 해준다.
  • 두 수 차이의 최댓값이 백만이기 때문에, 최솟값부터 시작해서 최댓값까지만의 배열을 만들어서 걸러준다.

#include <iostream>

#define ull unsigned long long 

using namespace std;

ull mini, maxi;
bool val[1000001];                                      // 에라토스테네스의 체, min 과 max 사이의 값들에 대한 배열
int number;

int main(void)
{
    cin >> mini >> maxi;

    for(ull i = 2, cur, sum ; i * i <= maxi ; i++)      // 에라토스테네스의 체로 1보다 큰 제곱수를 걸러냄
    {
        cur = i * i;                                    // cur 은 현재 반복문의 제곱값
        sum = mini - (mini % cur);                      // 거를 값, 어차피 min 과 max 사이 값들만 확인하므로 min 근처 값부터 확인한다
        while(sum <= maxi)
        {
            if(sum >= mini)
            {
                val[sum - mini] = true;                 // 제곱값의 배수라면 val 의 해당 인덱스에 표시
            }
            sum += cur;
        }
    }
    for(int i = 0 ; i <= maxi - mini ; i++)             // 전체 배열들 중 걸러지지 않은 값들의 갯수를 셈
    {                                                   // 범위는 max - min 값까지
        if(val[i] == false) number++;
    }
    cout << number << endl;
}

'PS > BOJ' 카테고리의 다른 글

[백준] 9465.cpp : 스티커  (0) 2020.07.27
[백준] 11053.cpp : 가장 긴 증가하는 부분 수열  (0) 2020.07.26
[백준] 15657.cpp : N과 M (8)  (0) 2020.07.25
[백준] 15654.cpp : N과 M (5)  (0) 2020.07.24
[백준] 15652.cpp : N과 M (4)  (0) 2020.07.23

+ Recent posts