Skip to content
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
72 changes: 72 additions & 0 deletions [3월 18일] 브루트포스/10757.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <iostream>
#include <string>
#include <stack>

using namespace std;

void Add(string A, string B) {
stack<int> a, b, res;

for (int i = 0; i < A.length(); i++) {
//문자를 정수로 바꾸기
int x = A[i] - '0';
// 계산하기 위해 스택에 넣기 (일의 자리부터)
a.push(x);
}

for (int i = 0; i < B.length(); i++) {
int y = B[i] - '0';
// 계산하기 위해 스택에 넣기 (일의 자리부터)
b.push(y);
}

// 스택 이용하여 계산
// 덧셈 시 올려 더해줘야되는 수 저장
int up = 0;

// 두 수 중에 더 큰 자리수를 cnt에 저장
int cnt = max(A.length(), B.length());

while (cnt--) {
// 만약 한 스택이 다 비면 남은 스택만 혼자 계산해주면 됨
if (a.empty() && !b.empty()) {
while (!b.empty()) {
res.push((b.top() + up) % 10);
up = (b.top() + up) / 10;
b.pop();
}
break;
}

else if (b.empty() && !a.empty()) {
while (!a.empty()) {
res.push((a.top() + up) % 10);
up = (a.top() + up) / 10;
a.pop();
}
break;
}

else if (a.empty() && b.empty()) break;

// 계산
res.push((a.top() + b.top() + up) % 10);
up = (a.top() + b.top() + up) / 10;
a.pop();
b.pop();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p2. 먼저 두개의 스택이 비어있지 않을 동안 값들을 계산하는 처리를 먼저 해주고, 그 이후에 A,B 스택에 남아있는 값들을 처리해주어도 괜찮았을 것 같아요! 아래 코드처럼요!

`while(!a.empty() && !b.empty) {
 //값 더하고 res에 푸시  }
while( !a.empty())  {// a에 원소가 남아있다면
 }
while( !b.empty()){  // b에 원소가 남아있다면
 }


// 결과 출력
if (up != 0) cout << up;
while (!res.empty()) {
cout << res.top();
res.pop();
}
}

int main() {
string A, B;
cin >> A >> B;
Add(A, B);
return 0;
}
57 changes: 57 additions & 0 deletions [3월 18일] 브루트포스/1759.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 틀린 코드입니다..! 피드백 해주시면 참고하여 수정하겠습니다!

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

/* 제 시도는 일단
1. 먼저 '개수' 충족하는 문자열을 모두 만들고 (조합 이용하여)
* 2. 그 문자열에 모음이 하나라도 없으면 안된다는 조건을 확인하여 걸러내는 작업을 하고 싶었는데요..
* next_permutation을 사용해보려고 했는데 아직 익숙치가 않아서.. 잘 모르겠습니다..
*/


int main() {
int l, c;
// l = 암호 길이, c =문자 종류 개수
cin >> l >> c;
// 문자 종류 담는 벡터
vector<char> ch(c);

// permutation 사용 위한 벡터
vector<int> temp(c);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p1.
temp(c) 로 초기화해주면 c만큼의 원소가 0으로 초기화되어요 😂 따라서 이 코드를 33번째 줄까지 완료한후의 temp의 크기는 c가 아니라 c+c 가 될거에요!

// 결과 출력 위한 벡터
vector<char> res;

// 입력
for (int i = 0; i < c; i++) cin >> ch[i];

// permutation 위해서, temp 벡터에 l개 만큼 1을 넣어준다
for (int i = 0; i < l; i++) temp.push_back(1);
for (int i = l; i < c; i++) temp.push_back(0);

// 정렬해야
sort(ch.begin(), ch.end());
Copy link
Copy Markdown

@flowersayo flowersayo Mar 24, 2022

Choose a reason for hiding this comment

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

p1.
지금 조합을 구하기 위해서 tmp 벡터에 l개만큼 1을 넣어주시고 next_permutation 을 돌려주셨네요! 그러나 next_permutation 을 활용하기 위해서는 temp 벡터에 반드시 오름차순 정렬을 먼저 수행해주셔야합니다. next_permutation 은 현재 수보다 다음으로 큰 수를 찾는 방식으로 모든 순열을 구하는 함수이기 때문입니다! 반면 현재 tmp 벡터는 1,1,1,1,0,0 로 초기화 되어있으니 (c=6, l=4일때를 예시로 들음) 다음번째로 큰 수가 존재하지 않으므로 모든 경우의 수를 구하지 못하고 조합 하나만 반환할 것입니다! 그래서 아래와 같이 정렬 후 활용해주셔야 모든 경우의 수를 구할 수 있습니다!

// permutation 위해서, temp 벡터에 l개 만큼 1을 넣어준다
	for (int i = 0; i < l; i++) temp.push_back(1);
	for (int i = l; i < c; i++) temp.push_back(0);

	
	sort(ch.begin(), ch.end());
	sort(temp.begin(), temp.end()); // temp 를 오름차순 정렬

	do {
		for (int i = 0; i < c; i++) {
			// 모음 개수
			int v_cnt = 0;

			if (temp[i] == 1) {
				cout << ch[i]<<" ";
			}
		}
		cout << '\n';
	} while (next_permutation(temp.begin(), temp.end()));

그러나 사실 위 결과대로 출력해도 제대로된 결과를 얻지 못합니다. 왜냐하면 모든 경우의 수를 구할 수는 있지만, 사전순으로 단어들을 출력하지는 못하기 때문입니다. temp를 오름차순 정렬한 후 next_permutation으로 조합을 구하면 temp는 반복문을 돌때마다 아래와 같은 변화를 거치게 됩니다.

 0 0 1 1 1 1 
 0 1 0 1 1 1 //  0 0 1 1 1 1 보다 다음번째로 큰수 
 0 1 1 0 1 1 //   0 1 0 1 1 1 보다 다음번째로 큰수 
  ...
 1 1 1 1 0 0

따라서 위 코드의 결과는 아래와같이 사전순과 정 반대되는 순서로 문자열을 출력하게 됩니다!
20220324152027

이럴때에는 내림차순 정렬된 컨테이너에서도 조합을 구할 수 있도록 해주는 prev_permutaion을 이용해볼 수 있습니다! 관련 링크 첨부하니 참고하셔서 문제 해결에 도움이 되었으면 하는 바람입니다 :)

https://twpower.github.io/82-next_permutation-and-prev_permutation


do {
for (int i = 0; i < c; i++) {
// 모음 개수
int v_cnt = 0;
if (temp[i] == 1) {
res.push_back(ch[i]);
if (ch[i] == 'a' || ch[i] == 'e' || ch[i] == 'i' || ch[i] == 'o' || ch[i] == 'u') v_cnt++;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p1.
지금 모음이 하나이상있는지 체크하는 부분은 있는데 자음이 두개이상 최소 존재하는지 체크하는 부분이 없네요!


if (i == c - 1 && v_cnt < 1) continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p1.
v_cnt < 1 일 경우는 어짜피 조건문에 걸리지 않으니 굳이 적어주지 않아도 될 것 같아요!

else if (i == c - 1 && v_cnt >= 1) {
for (int j = 0; j < l; j++) cout << res[j];
}
else continue;
Copy link
Copy Markdown

@flowersayo flowersayo Mar 24, 2022

Choose a reason for hiding this comment

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

p1.
이 부분도 마찬가지에요 어짜피 반복문에 끝에 위치하니 continue가 의미 없겠죠!

}
}
cout << '\n';
} while (next_permutation(temp.begin(), temp.end()));

return 0;
}
61 changes: 61 additions & 0 deletions [3월 18일] 브루트포스/2503.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
int n;
// 테스트케이스 개수
cin >> n;

// n개씩 할당된 배열들 = 각각 테스트 되는 정수, 해당 정수의 스트라이크 개수와 볼 개수를 저장함
vector<string> test(n);
vector<int> strk(n), ball(n);

// 최종적으로 조건 만족하는 정수들을 넣는 벡터
// 구하고자 하는 개수는 벡터의 크기와 같음
vector<int> ans;

// 입력
for (int i = 0; i < n; i++) {
cin >> test[i] >> strk[i] >> ball[i];
}


// 가능한 정수들에 대해 일일이 비교
for (int i = 123; i <= 987; i++) {
// 각 자리수를 비교할 거라 문자열 형태로 바꾸어줌
string x = to_string(i);

// 여기서 시간 오래 걸림.. 문제 조건 제발 잘 확인!!!
// 0 사용 불가 & 각 자리수 다 다른 숫자임!!
if (x[0] == '0' || x[1] == '0' || x[2] == '0' || x[0] == x[1] || x[1] == x[2] || x[0] == x[2]) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

숫자에 0이 포함되어있을 경우 답으로 카운트될 수 없다는 코너케이스를 잘 캐치해주셨네요👍👍👍


// 숫자 i에 대해 숫자 야구 진행해서 -> 모든 테스트 케이스와 각각의 결과 같은지 비교
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

맞아요! 모든 경우의 수를 다 해보는 것 이게 바로 브루트포스죠 👍

for (int j = 0; j < n; j++) {
int test_strk = 0, test_ball = 0;

// 각 자리수에 대해, 즉 총 3회 비교
for (int k = 0; k < 3; k++) {
// 스트라이크 확인
if (x[k] == test[j][k]) test_strk++;

// 볼 확인
if (x[k] == test[j][(k + 1) % 3] || x[k] == test[j][(k + 2) % 3]) test_ball++;
}

// 모든 테스트 케이스에 대해 결과값 같을 때 해당하는 정수 i를 ans 벡터에 넣어줌
if (test_strk == strk[j] && test_ball == ball[j]) {
if (j == n - 1) ans.push_back(i);
continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p1.
이부분 continue도 불필요한 것 같아요!

}
else break;
Copy link
Copy Markdown

@flowersayo flowersayo Mar 24, 2022

Choose a reason for hiding this comment

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

p1.
반복문을 n회 돌때마다 매번 조건을 체크하는데다가 n회중 마지막 1번만 조건이 참이 될테니 반복문안에서 확인하는 것은 조금 비효율적이어보여요! 이부분은 for문 밖에 작성하면 마지막루프인지 확인하는 if (j == n - 1) 라는 중첩 if문을 작성할 필요가 없어지는데다가 한번의 조건 체크만으로도 가능해지니 훨씬 깔끔할 것 같아요! 그런데 물론 모든 테스트케이스가 일치했는지 저장해주는 bool변수가 추가적으로 필요하겠죠,,!

}
}

// 모든 조건 만족하는 정수가 들어있는 벡터의 사이즈를 출력
cout << ans.size();

return 0;
}
58 changes: 58 additions & 0 deletions [3월 18일] 브루트포스/2798.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

/* 질문. 이 문제에서 '메모리 사용량'을 줄일 수 있는 방법이 있을까요..? 무엇이 메모리 사용량을 크게 만드는 요소인지 궁금합니다!
* C++를 사용하여 문제를 푸신 다른 분들의 제출에 비해 제 코드가 메모리 사용량이 크더라구요..
*/


// diff가 작은 순서대로 정렬하는 비교함수
bool cmp(pair<int, int> v1, pair<int, int> v2) {
return v1.first < v2.first;
}


void Blackjack(int n, int m) {
// 카드값 입력 받기 위한 벡터
vector<int> v(n);

// 차이값, 합 저장하기 위한 벡터 -> 이후에 차이값을 작은 순서대로 정렬해서 -> 가장 작은 차이값을 가질 때의 합을 출력하도록 할 것임
vector<pair<int, int>> res;

for (int i = 0; i < n; i++) {
// 카드 입력받아서 벡터에 저장
cin >> v[i];
}

int sum = 0;
// 3장이니까 그냥 차례차례 3개씩 묶어주는데 이때 시작 조건 주의했어야!!
// j,k는 각각 i,j의 다음(즉, i+1, j+1)부터라는 게 중요
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p2.
지금도 잘 작성해주셨는데요 ! 세장의 카드를 뽑는 반복문은 보통 이런식으로 많이 작성하는것 같아요!👍

for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            for (int k = j + 1; k < n; k++) {

// 각 카드의 합을 더해줌
sum = v[i] + v[j] + v[k];
int diff = m - sum;
// diff < 0 이라는 건 합이 m을 넘는다는 거니까 조건 충족 X
if (diff < 0) continue;
// 조건 충족시에만 차이값, 합을 벡터에 넣어준다
else res.push_back({ diff, sum });
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

p1.
지금 조건을 만족하는(=m이하의 합을 지니는) 경우가 생길때마다 모두 res 벡터에 푸시하고
res벡터에서 diff 가 가장 작은 값을 찾아서 그때의 sum을 출력해주는 방식으로 코드를 작성해주셨어요!

그런데 과연 조건을 하나만 더 추가하면 굳이 번거롭게 벡터를 만들고 모든 경우의 수를 푸시시켜 정렬시키지 않고도 간단하게 정답을 구할 수 있을 것 같아요! res에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 담는다고 해볼께요 sum은 반드시 m보다 작아야하죠? 그렇다면 res를 어느 경우에 갱신시킬 수 있을까요?

}
}
}

// 차이가 작은 순서대로 정렬 -> v[0]에는 차이값이 가장 작을 때의 경우!
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

위 커멘트를 참고하셔서 고치신다면 이부분도 필요가 없어지겠죠?!

sort(res.begin(), res.end(), cmp);

// 그때의 합을 출력해주면 됨
cout << res[0].second;
}

int main() {
int n, m;
cin >> n >> m;
Blackjack(n, m);
return 0;
}
24 changes: 24 additions & 0 deletions [3월 18일] 브루트포스/2858.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 다소 무식하게 연립방정식 & 근의 공식을 사용했습니다..
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

전혀 그렇지 않은걸요🥺🥺
저는 이런식으로도 접근해서 풀 수도 있구나 하면서 깜짝놀랐어요!
코드도 깔끔해서 좋아요👍

void Tile(const int& R, const int& B) {

int res1 = (R + 4) / 2;
int res2 = R + B;

int x = (res1 + sqrt(res1 * res1 - 4 * res2)) / 2;
int y = res1 - x;

cout << max(x, y) << ' ' << min(x, y);
}

int main() {
int R, B;
cin >> R >> B;
Tile(R, B);
return 0;
}