[복습]260929 - 조건문
8조건문 연습문제 - 7번
Q7. 공동 1위 발표
문제
철수·영희·민수의 점수를 순서대로 한 줄씩 입력받음. 최고 점수가 60 이상이면 최고 점수를 받은 사람 모두를 선발함. 선발된 이름과 점수를 철수·영희·민수 순서로 출력하고 마지막에 선발 인원을 출력함. 아무도 선발되지 않으면 선발자 없음과 선발 인원 0을 출력함. 점수는 0~100의 정수임.
입력 예시
85
72
85
예상 결과
철수: 85
민수: 85
선발 인원: 2
using System;
//철수·영희·민수의 점수를 순서대로 한 줄씩 입력받음.
int chul = int.Parse(Console.ReadLine());
int young = int.Parse(Console.ReadLine());
int min = int.Parse(Console.ReadLine());
int pick = 0;
int best = chul; //일단 철수한테 최고를 넣어봄
if (young > best) // 최고랑 영희랑 비교하고 영희가 더 높으면
{
best = young; // 영희한테 벨트 넘김
}
if (min > best) // 최고랑 민수랑 비교하고민수가 지금 벨트 주인보다 높으면
{
best = min; // 민수한테 벨트 넘김
}
//이러면 어찌됬든 best에는 최고값이 들어가게됨
//최고값을 구했으니 최고값이랑 같은애들을 비교하자
//60 이상이라는 최소기준 보면서
if (best >= 60)
{
if(chul == best)
{
Console.WriteLine($"철수: {best}");
pick++;
}
if(young == best)
{
Console.WriteLine($"영희: {best}");
pick++;
}
if(min == best)
{
Console.WriteLine($"민수: {best}");
pick++;
}
}
else
{
Console.WriteLine($"선발자 없음");
}
//일단 점수를 입력받고 여기서 같은애들만 뽑아야하는데
//서로서로 같은걸 어떻게 계산하냐고
//
Console.WriteLine($"선발 인원: {pick}");
왜 못풀었나?
- "최고 점수"를 "60점 이상인 점수"로 잘못 읽어서, 60점 넘는 사람을 전부 선발하려고 함
- 세 명을 서로서로 비교하려다 경우가 너무 많아져서 막힘
- 최고값을 먼저 구하는 방법(패턴)을 몰랐음
알게된점?
- 최고값은 "일단 첫 번째에 벨트를 주고, 다음 사람이 더 크면 넘겨준다" 방식으로 구함
- 서로서로 비교할 필요 없이, 최고값 하나를 구한 뒤 각자 그 값이랑만 비교하면 됨 (공동 1위도 자연스럽게 처리)
- 60 조건은 최고값 하나에만 바깥 if로 걸고, 안쪽 if로 각자 확인 (이중 if)
- 아무도 안 뽑히는 경우는 else로 따로 처리
8조건문 연습문제 - 8번
Q8. 설정값 우선순위
문제
명령줄 설정과 파일 설정을 문자열 한 줄씩 입력받음. int로 변환할 수 있고 1~100인 설정만 유효함. 명령줄 설정이 유효하면 그것을 사용하고, 그렇지 않으면 유효한 파일 설정을 사용함. 둘 다 유효하지 않으면 기본값 20을 사용함. 선택한 출처와 최종 값을 출력함. 빈 줄·변환 실패·범위 오류는 모두 유효하지 않은 설정으로 취급함.
입력 예시
오류
35
예상 결과
출처: 파일
설정값: 35
using System;
string order = Console.ReadLine(); //명령줄
string setting = Console.ReadLine(); //파일설정
bool orderOk = int.TryParse(order, out int orderValue);
bool settingOk = int.TryParse(setting, out int settingValue);
//명령이 변환 성공했고 그게 허용 범위 내
if(orderOk && orderValue >= 1 && orderValue <= 100)
{
Console.WriteLine("출처: 명령줄");
Console.WriteLine($"설정값: {orderValue}");
}
//세팅이 변환 성공했고 허용 범위 내
else if(settingOk && settingValue >= 1 && settingValue <= 100)
{
Console.WriteLine("출처: 파일");
Console.WriteLine($"설정값: {settingValue}");
}
else
{
Console.WriteLine("출처: 기본값");
Console.WriteLine("설정값: 20");
}
왜 못풀었나?
- 출력의 "명령줄", "파일"이 어디서 나오는 값인지 몰랐음 (문제가 입력 줄에 붙인 이름이라 직접 적는 텍스트였음)
- 명령줄 유효 검사에 파일 값(settingValue)을 섞어 씀
- TryParse 복사 후 변수명을 안 바꿔서 setting 대신 order를 두 번 변환함
- if 두 개로 짜서 우선순위가 안 지켜짐
알게된점?
- 출처처럼 고정된 글자는 따옴표 안에 직접 적으면 됨
- "유효하다" = TryParse 성공 && 범위 안. 각 입력은 자기 변수로만 검사
- 1순위, 2순위, 기본값 같은 우선순위는 if / else if / else로 위에서부터 먼저 통과한 것 하나만 사용
- 복사한 줄은 괄호 안 변수까지 바뀌었는지 확인할 것
Q9. 출력 범위 자르기
문제
문서는 1100페이지임. 출력할 시작·끝 페이지를 한 줄씩 입력받으며 두 끝을 모두 포함함. 시작이 끝보다 크면 잘못된 순서만 출력함. 순서가 맞지만 실제 문서와 겹치는 페이지가 없으면 출력할 페이지 없음만 출력함. 그 외에는 존재하는 페이지 구간만 출력 대상으로 삼아 실제 범위·출력 장수·요청에서 제외된 장수를 출력함. 두 입력은 -10001000의 정수임.
입력 예시
98
105
예상 결과
출력 범위: 98~100
출력 장수: 3
제외된 장수: 5
using System;
using System.Drawing;
int start = int.Parse(Console.ReadLine());
int end = int.Parse(Console.ReadLine());
// 두 끝을 모두 포함함. <= 뭔소리여
//두끝이 뭔데
//시작이 끝보다 크면 잘못된 순서만 출력함
//순서가 맞지만 실제 문서와 겹치는 페이지가 없으면
//출력할 페이지 없음만 출력함
//그 외에는 존재하는 페이지 구간만 출력 대상으로 삼아
//실제 범위·출력 장수·요청에서 제외된 장수를 출력
//제외된 장수 = 범위 벗어난만큼
//일단 아예 틀린경우
if(start > end)
{
Console.WriteLine("잘못된 순서");
}
//start가 0보다 작거나 100보다 크다면 (둘중에 하나라도 포함일시)
//이게 아닌데? 겹치는게 없다는건 start end 전부 범위 아웃이라는거아닌가
else if (end < 1 || start > 100) //끝이 1보다 작고 시작이 100보다 큰 안겹치는 문제상황
{
Console.WriteLine($"출력할 페이지 없음");
}
else
{
int realStart = start < 1 ? 1 : start;
int realEnd = end > 100 ? 100 : end;
int print = (realEnd - realStart) + 1;
int request = (end - start) + 1;
int ignore = request - print;
Console.WriteLine($"출력 범위: {realStart}~{realEnd}");
Console.WriteLine($"출력 장수: {print}");//-1 한 이유? 해당 장까지 포함해야하니까
Console.WriteLine($"제외된 장수: {ignore}");//그냥 end에서 100빼면 되는거 아님?
}
왜 못풀었나?
- "두 끝을 모두 포함"의 뜻이 헷갈림 (사실 주석에 쓴 +1이 그 뜻이었음)
- 끝 페이지를 항상 100으로 고정해서 10~20 같은 입력에서 틀림
- 페이지 기준을 1이 아니라 0으로 잡음
- else 안에서 만든 변수를 중괄호 밖에서 출력하려다 에러 (스코프)
- 새 코드 아래 예전 코드가 남아서 else 뒤에 else if가 붙는 에러
알게된점?
- 요청 범위를 실제 범위(1~100) 안으로 자르기: realStart = start < 1 ? 1 : start, realEnd = end > 100 ? 100 : end
- 두 끝 포함 장수 = 끝 - 시작 + 1
- 제외된 장수 = 요청 장수(자르기 전) - 출력 장수(자른 후). 둘 다 자른 값으로 계산하면 0이 됨
- 겹치는 페이지 없음 = end < 1 || start > 100
- 중괄호 안에서 만든 변수는 밖에서 못 씀. 그 경우에만 필요한 출력은 중괄호 안에 둘 것
Q10. 주문 상태 변경
문제
현재 주문 상태, 현재 잔액, 처리할 명령을 한 줄씩 입력받아 주문 하나를 처리함. 주문 금액은 3000원이며 현재 상태는 접수·결제·발송·취소 중 하나, 잔액은 0~100000의 정수임. 결제·발송 상태의 잔액은 이미 주문 금액을 지불한 뒤의 값임. 명령은 대소문자를 구분함.
- pay: 접수 상태에서만 결제할 수 있음. 잔액이 충분하면 3000원을 차감하고 결제로 바꾸며 결제 완료를 출력함. 부족하면 잔액 부족, 다른 상태라면 결제할 수 없는 상태를 출력함.
- ship: 결제 상태만 발송으로 바꾸고 발송 완료를 출력함. 다른 상태이면 발송할 수 없는 상태를 출력함.
- cancel: 접수 상태이면 취소로 바꾸고 접수 취소를 출력함. 결제 상태이면 3000원을 환불하고 취소로 바꾸며 결제 취소 및 환불을 출력함. 발송이면 발송 후 취소 불가, 취소이면 이미 취소됨을 출력함.
- 그 외 명령은 알 수 없는 명령을 출력함.
거절된 명령은 상태와 잔액을 바꾸지 않음. 처리 메시지 다음에 최종 상태와 잔액을 출력함.
입력 예시
결제
2000
cancel
예상 결과
결제 취소 및 환불
상태: 취소
잔액: 5000



