일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 이분 탐색
- 문자열
- 다익스트라
- 알고리즘
- 2023
- 분할 정복
- DP
- 세그먼트 트리
- 플로이드 와샬
- tensorflow
- 백트래킹
- back propagation
- 미래는_현재와_과거로
- BFS
- 크루스칼
- c++
- object detection
- dropout
- 조합론
- lazy propagation
- pytorch
- 너비 우선 탐색
- 가끔은 말로
- 자바스크립트
- 회고록
- NEXT
- 가끔은_말로
- 우선 순위 큐
- dfs
- Overfitting
Archives
- Today
- Total
Doby's Lab
백준 4233번: 가짜소수 (C++) 본문
https://www.acmicpc.net/problem/4233
4233번: 가짜소수
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, p와 a를 포함하고 있다. 입력의 마지막 줄에는 "0 0"이 주어진다. (2 < p ≤ 1,000,000,000, 1 < a < p)
www.acmicpc.net
Solved By: Exponentiation By Squaring, Primality Test
페르마의 소정리 개념을 공부하려다가 풀게 된 문제입니다.
입력값으로 p와 a가 들어오면 a ^ p를 구하고 p로 나누었을 때, a인지 판정 후에 나누었던 p가 소수인지 아닌지를 판정하면 끝나는 문제입니다.
다만, int형의 오버플로우, 분할 정복을 이용한 거듭제곱, Modular의 분배 법칙, 소수 판정 방법을 알아야 문제를 풀 수 있습니다.
int 형의 오버플로우를 해결하기 위해서는 long long 타입으로 변수들을 선언하여 풀었고,
a^p에서 p의 숫자가 큰 수가 나올 수도 있어서 이를 빠른 시간 안에 해결하기 위해 분할 정복을 이용한 거듭제곱을 사용했습니다.
거듭제곱을 하는 과정에서 오버플로우가 나올 수도 있기 때문에 Modular 분배 법칙을 활용하여 리턴하는 value 값에 p를 Modular 연산해주었습니다.
그리고, 소수 판정 방식에 있어서는 2부터 root N까지만 확인을 하여 약수가 없는 경우를 소수로 판정하여 더 빠르게 리턴하도록 해주었습니다.
#include <iostream>
#include <vector>
#include <cmath>
#define ll long long
using namespace std;
ll mod;
ll POW(ll a, ll b){
if(b == 0) return 1;
else if(b == 1) return a;
ll value = POW(a, b / 2) % mod;
if(b % 2){
return (((value * value) % mod) * (a % mod)) % mod;
}
else{
return (value * value) % mod;
}
}
bool isPrime(ll n){
for(int i = 2; i <= sqrtl(n); i++){
if(n % i == 0) return false;
}
return true;
}
int main(){
vector<string> ans;
while(true){
ll p, a; cin >> p >> a;
if(p == 0 && a == 0) break;
mod = p;
if((POW(a, p) % p) == a){
// p가 가짜 소수인지 아닌지 판정
if(isPrime(p)) ans.push_back("no");
else ans.push_back("yes");
}
else ans.push_back("no");
}
for(int i = 0; i < ans.size(); i++){
cout << ans[i] << '\n';
}
return 0;
}
728x90
'PS > BOJ' 카테고리의 다른 글
백준 13905번: 세부 (C++) (0) | 2022.06.26 |
---|---|
백준 2042번: 구간 합 구하기 (C++) (0) | 2022.06.25 |
백준 14565번: 역원(Inverse) 구하기 (C++) (0) | 2022.06.21 |
백준 11256번: 사탕 (C++) (0) | 2022.06.19 |
백준 15720번: 카우버거 (C++) (0) | 2022.06.19 |