#include <iostream>
using namespace std;
int main()
{
int chess[6] = { 1,1,2,2,2,8 }; //기준
int res[6] = {}; //결과
int input; //찾은 개수
for (int i = 0; i < 6; i++) {
cin >> input;
if (input < chess[i]) { //부족한 경우
while (input < chess[i]) {
input++;
res[i]++;
}
cout << res[i] << " ";
}
else if (input > chess[i]) { //넘치는 경우
while (input > chess[i]) {
input--;
res[i]--;
}
cout << res[i] << " ";
}
else { //맞는 개수인 경우
cout << res[i] << " ";
}
}
return 0;
}
★처음엔 위와 같이 풀었는데 이게 왜 최하위 레벨이지,,, 하고 다른 사람들 코드를 보니까 그냥 내가 더 복잡하게 푼 것이었다. 나는 경우를 나누어서 올리거나 내리는 식으로 했는데 그냥 chess배열 기준 값에서 찾은 input값을 빼주면 된다. (항상 이런 기본적인 걸 한 번에 못 떠올림,,,ㅠ <- 그러니까 문제 많이 풀어서 감을 잡자!!!)
#include <iostream>
using namespace std;
int main()
{
int chess[6] = { 1,1,2,2,2,8 }; //기준
int input; //찾은 개수
for (int i = 0; i < 6; i++) {
cin >> input;
cout << chess[i] - input << " ";
}
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) { //위 절반 삼각형
for (int j = 1; j <= n - i; j++) { //n-i개 공백
cout << " ";
}
for (int k = 1; k <= 2*i - 1; k++) { //2i-1개 별
cout << "*";
}
cout << "\n";
}
for (int i = n - 1; i > 0; i--) { //아래 절반 삼각형
for (int j = 1; j <= n - i; j++) { //n-i개 공백
cout << " ";
}
for (int k = 1; k <= 2 * i - 1; k++) { //2i-1개 별
cout << "*";
}
cout << "\n";
}
return 0;
}
☆찍기 문제는 바로 생각나지 않을 수 있다. 이럴 때는 화면 보면서 한번에 풀겠답시고 멍 때리지 말고 그냥 바로 메모장을 켜서 규칙을 찾아보자,,,(멍 때리다 포기하고 침대에 누울 뻔하다)
먼저 출력 단계는 전체 라인->공백->별 출력으로 3중 for문으로 구성하면 된다. (뒤에 공백은 그냥 외관상 보이는 용이라 출력 필요 x) 그리고 위 삼각형만 살펴 봤을 때, i라인마다 n-1 공백 출력 후 별을 2i-1개씩 찍는 것을 알 수 있다. 이 공식 그대로 for문 조건으로 작성한다. 아래 삼각형은 반대로 출력해야 하는데, 전체 for문 조건만 반대로 바꿔주면 안의 for문은 그대로 해도 괜찮다.
#include <iostream>
using namespace std;
int main()
{
string s;
cin >> s;
int len = s.length() - 1;
int count = 0;
for (int i = 0; i < s.length() / 2; i++) {
if (s[i] != s[len--]) {
cout << "0";
return 0;
}
}
cout << "1";
return 0;
}
★이런 문제는 예전에 풀었던 문제와 같은 형식으로 풀면 된다. 팰린드롬일 경우 홀수 문자가 가운데 문자를 기준으로 양옆끼리 똑같으면 되는 것이기 때문에, 길이/2만큼 반복하면서 양끝끼리 비교하면 된다. 다를 시 바로 종료되도록 하면 굳이 추가의 count변수로 확인 작업 필요 없이, 종료되지 않고 for문이 끝났다는 것만으로도 팰린드롬이라는 것이 확인된다.
#include <iostream>
using namespace std;
int main()
{
int alpa[26] = {}; //대소문자 구분x, 빈도수 저장
int max = -1, sameMax = 0, maxAlpa = 0;
string s;
cin >> s;
for (int i = 0; i < s.length(); i++) {
if (s[i] >= 'a') { //소문자인 경우
alpa[(int)s[i] - 'a']++; //a를 0부터 시작
}
else { //대문자인 경우
alpa[(int)s[i] - 'A']++; //A를 0부터 시작
}
}
for (int i = 0; i < 26; i++) {
if (alpa[i] > max) {
max = alpa[i];
maxAlpa = i;
}
else if (alpa[i] == max) {
max = alpa[i];
maxAlpa = i;
sameMax = max;
}
}
if (max == sameMax) {
cout << "?";
}
else {
cout << (char)(maxAlpa +'A');
}
return 0;
}
★대소문자를 구분하여 같은 인덱스로 변환하는 for문을 먼저 만들어준다. 이후 다시 for문으로 배열을 처음부터 검사하면서 max값과 해당 index값을 저장해 준다. 또한 같은 최댓값인 경우 sameMax값도 설정해 주어서, 마지막에 if else문으로 검사하여 출력하는 형식으로 구현하였다. 하지만 이 방법으로 하니 메모리와 시간이 많이 걸렸다(...) 그래서 다른 방법을 찾아보니, 배열을 검사하는 과정에서 한번에 출력 값을 미리 설정해 놓는 방법이 있었다. 수정된 부분은 아래와 같다. (근데 막상 해보니까 그렇게 큰 차이는 안 남 ㅇㄴ 다른 데도 더 수정해야 하는 듯,,,)
for (int i = 0; i < 26; i++) {
if (alpa[i] > max) {
max = alpa[i];
res = 'A' + i;
}
else if (alpa[i] == max) {
res = '?';
}
}
cout << res;
#include <iostream>
using namespace std;
int main()
{
int count = 0;
string s;
cin >> s;
for (int i = 0; i < s.length(); i++) {
if (s[i] == 'd' && s[i+1] == 'z' && s[i+2] == '=') {
count++;
i += 2;
}
else if (s[i] == 'l' && s[i+1] == 'j') {
count++;
i += 1;
}
else if (s[i] == 'n' && s[i+1] == 'j') {
count++;
i += 1;
}
else if (s[i] == '-' || s[i] == '=') {
continue;
}
else {
count++;
}
}
cout << count;
return 0;
}
드디어 실버 문제 진입!! (사실 브론즈에서 막힐 때마다 상당히 현타 왔었음) ★처음에는 s[i++]형식으로 구현하여 접근과 동시에 인덱스가 자동 업데이트 되도록 하였다. 그런데 내 환경에서는 예제 입력 모두 성공했는데, 백준에서 돌리니까 바로 오류가 났다. 이건 내 코드를 검사하기 위해서 gpt한테 물어보니까 i++로 하는 건 상황에 따라 오류가 날 수 있으므로 i+1로 접근한 다음에 나중에 i+=2를 하는 식으로 업데이트하는 것이 더 좋은 방법이라고 한다...ㅇㅋ 생각해 보니까 어셈블리 강의 들을 때도 비슷한 얘기를 교수님께서 해주셨던 거 같다. 아무튼 결론: 전위, 후위 연산자보다 그냥 +=으로 하는 것이 더 정확하다!!
#include <iostream>
using namespace std;
int main()
{
int n, bk, count = 0;
string s;
cin >> n;
for (int i = 0; i < n; i++) {
bk = 0;
cin >> s;
for (int j = 0; j < s.length(); j++) {
for (int k = j+1; k < s.length(); k++) {
if (s[j] == s[k] && s[k - 1] != s[k]) {
bk = 1; //다시 cin으로 돌아감
break;
}
}
if (bk == 1) break;
}
if (bk == 0) count++;
}
cout << count;
return 0;
}
☆알파벳 배열을 만들어서 기록하는 형식이 아니라 바로 비교하는 형식으로 구현하였다. 전체 for문에서는 n만큼 반복하여 입력을 받고, 첫 번째 문자부터 j로 반복하면서 그다음 문자 k와 비교를 한다. 예를 들어, aabbbccb 문자열이 있을 때, j는 a를 기준으로 하여 k가 a, b, b, b, c, c, b와 비교를 하게 된다. 여기서 다 건너뛰다가 j가 (첫 번째) b가 됐을 때, k가 (두 번째) b부터 검사한다. 그러다가 마지막 b가 나오면 if문에 걸리게 된다. j랑 k가 같은 b인데 k-1인 c와는 다르기 때문이다. 이렇게 되면 멈추고 맨 처음 for문으로 돌아가서 새 문자열을 입력받아야 하는데, goto문이었나,,, 그걸 쓰는 건 좋지 않다고 배워서 애초에 쓰는 법도 모른다. 그래서 그냥 break point 변수를 만들어서 처음 for문으로 돌아가게 만들었다.
#include <iostream>
using namespace std;
int main()
{
string major, grade;
double time, res = 0, timeSum = 0;
for (int i = 0; i < 20; i++) {
cin >> major >> time >> grade;
if (grade == "P") continue;
timeSum += time;
switch (grade[0])
{
case 'A':
if (grade[1] == '+') res += time * 4.5;
else res += time * 4.0;
break;
case 'B':
if (grade[1] == '+') res += time * 3.5;
else res += time * 3.0;
break;
case 'C':
if (grade[1] == '+') res += time * 2.5;
else res += time * 2.0;
break;
case 'D':
if (grade[1] == '+') res += time * 1.5;
else res += time * 1.0;
break;
default:
break;
}
}
printf("%.5lf", res/timeSum);
return 0;
}
★switch문을 사용할 때, 변수로는 숫자나 문자만 올 수 있다. 문자열 그대로 넣으려면 따로 해시 함수나 직접 구현해야 한다. 그래서 첫 문자로만 구분을 하고 두 번째 +/0 문자는 if문으로 구분을 하였다. 이럴 거면 그냥 처음부터 if문으로 해도 됐었지만 그냥 switch문이 쓰고 싶었다. 그런데 오랜만에 써서 각 case마다 break를 빼먹었더니 값이 이상하게 나와서 한참 헤맸다. (if문으로 하든가 break를 잊지 말자......) 아무튼 6단계도 이렇게 끝~!~!!