Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ 정수론 ] 9월 6일 #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions 03_정수론/1735.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

#include <iostream>

using namespace std;

int getGcd(int a, int b) {
int tmp;
while (b != 0) {
tmp = a % b;
a = b;
b = tmp;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유클리드 호제법을 반복문으로 구현해주셨네요! 잊지 않고 swap해주시는 것까지 아주 좋습니다!

return a;
}


int main()
{
int a1, a2, b1, b2, c1, c2;

cin >> a1 >> a2;
cin >> b1 >> b2;

c1 = a1*b2 + a2*b1;
c2 = a2*b2;

int gcd_c = getGcd(c1,c2);

c1/=gcd_c;
c2/=gcd_c;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

통분하고 약분해주는 과정도 깔끔하네요👍👍


cout << c1 << ' ' << c2;

return 0;
}
59 changes: 59 additions & 0 deletions 03_정수론/2840.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <iostream>
#include <vector>

using namespace std;

int main()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. main 함수에서는 입출력만 하고 추가적인 연산은 따로 함수로 작성해주는게 좋아요!

{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

int n, k, pt;

cin >> n >> k;

vector<char> arr(n,'?');

for(int i=0;i<k;i++){
int turns;
char c;
Comment on lines +19 to +20

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for문 안에서 변수를 정의하면 반복문을 돌때마다 새로 할당해주게 돼요! 반복문 밖에서 한번만 정의해준 후 값만 바꿔주는 게 좋습니다~


cin >> turns >> c;

if(i==0){
pt=i;
arr[i]=c;
continue;
}
Comment on lines +24 to +28

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫 번째 경우는 무조건 넣을 수 있으니까 예외처리해준 거 좋아요! 다만 for문을 돌때마다 i가 0인지 검사하게 되니까 n이 커지면 시간복잡도 측면에서 비효율적인 코드가 될 수 있어요! 차라리 for문 바깥에서 i가 0일 때의 경우를 처리해주고 for문을 1부터 실행하는 게 어떨까요? 아니면 굳이 검사하지 않아도 괜찮아요!


pt=(pt+turns)%n;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

화살표의 위치를 옮겨주는 과정을 잘 구현해주셨네요! 👍

if(arr[pt]!='?' && arr[pt]!=c){
cout << "!";
return 0;
}
else{
arr[pt]=c;
}
Comment on lines +35 to +37

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위의 if문에서 return으로 함수를 종료시켰기 때문에 else라고 따로 작성해 줄 필요가 없어요! else를 쓰지 않으면 더 가독성 있는 코드가 됩니다!


}

for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(arr[i]!='?' && arr[i]==arr[j]){
cout << "!";
return 0;
}
}
}
Comment on lines +41 to +48

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 알파벳 중복 체크를 마지막에 한번에 진행해줬네요 이 경우에는 이중 반복문을 사용했기 때문에 n이 커지는 경우 시간복잡도 측면에서 비효율적일 수 있어요! 알파벳 중복 확인 벡터를 사용하여 위의 반복문 안에서 중복 체크를 해주는 게 어떨까요?


for(int i=0;i<arr.size();i++){
cout << arr[pt];
pt--;
if(pt<0){
pt=n-1;
}
Comment on lines +53 to +55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 이렇게 구현하면 매번 pt가 0보다 작은지 검사하게 되네요! 해당 조건문을 통과하는 경우는 최대 1번밖에 없으니 비효율적인 코드가 될 수 있을 것 같아요 for 문에서 i가 항상 양수가 되도록 범위를 설정해보는 것이 어떨까요?

}

return 0;
}
55 changes: 55 additions & 0 deletions 03_정수론/6588.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<bool> getPrimes(int n) { //소수 여부를 반환
vector<bool> is_prime(n + 1, true); //소수 여부를 저장할 벡터
is_prime[0] = is_prime[1] = false; //0과 1은 소수가 아니므로 false 저장
for (int i = 2; i * i <= n; i++) { //n의 제곱근보다 낮은 범위에서 탐색
if (!is_prime[i]) { //소수가 아닐 시
continue; //처음으로 되돌아감
}
for (int j = i * i; j <= n; j += i) { //배수는 제외
is_prime[j] = false; //배수는 제외
}
}
return is_prime; //결과 리턴(소수 여부가 저장된 벡터)
}


int goldbach(int n, vector<bool> &is_prime) { //n=a+b인 a 리턴
for (int a = 3; a <= n / 2; a+= 2) { //3부터 홀수 중 탐색(2보다 큰 짝수 소수는 존재하지 않기 때문)
if (is_prime[a] && is_prime[n - a]) { //n=a+b에서 a와 b가 모두 소수라면
return a; //n=a+b인 a 리턴
}
}
return 0; //해당하는 a와 b가 없으면 0 리턴
}

int main() { //메인함수
vector<int> arr; //배열 선언
int input; //입력값 받을 변수
while(1) { //무한반복
cin >> input; //입력 받기
if (input == 0) { //사용자가 0을 입력하면
break; //루프 끝
}
arr.push_back(input); //벡터 끝에 입력값 넣기
}

int max_num = *max_element(arr.begin(), arr.end()); //배열의 처음부터 끝까지 가장 큰 수를 저장(값 참조)
vector<bool> is_prime = getPrimes(max_num); //소수 얻기

for (int i = 0; i < arr.size(); i++) { //배열 내에서 반복
int a = goldbach(arr[i], is_prime); //n=a+b인 a 리턴

if (a != 0) { // n=a+b인 a, b가 존재하는 경우
cout << arr[i] << " = " << a << " + " << arr[i] - a << "\n"; //결과 출력
} else { //존재하지 않는 경우
cout << "Goldbach's conjecture is wrong.\n"; //결과 출력
}
}
return 0; //종료
}