본문 바로가기

분류 전체보기

(81)
2839)설탕 배달 https://www.acmicpc.net/problem/2839 이 문제 예제만 보면 3으로 먼저 나누고 그 나머지를 5로 나누어 풀면 되겠다는 느낌을 받았다. 마지막 예제를 보면 입력이 11일 때 최소 봉지의 수가 3이 나와야 한다. 3kg 설탕 봉지가 2개, 5kg 설탕 봉지가 1개여야 가능하다. 3으로 먼저 나누고 그 나머지를 5로 나누든 5로 먼저 나누고 그 나머지를 3으로 나누든, 단순하게 나눠서 얻을 수 없는 조합이다. 설탕이 Nkg일 때 5kg 설탕봉지 a개와 과 3kg 설탕 봉지 b개로 나타낼 수 있다. N = 5*b + 3*a (a,b는 정수) 식을 바꿔서 a에 대한 b의 함수로 나타낼 수 있다. b = (N-3*a)/3 여기서 a를 0부터 b가 음수가 되기 전까지 하나 씩 값을 올려가..
10773)제로 https://www.acmicpc.net/problem/10773 생각하기 넘 귀찮다. 쉬운 문제만 골라서 풀어야지. 문제 설명이 이해가 잘 안됬는데 힌트에 잘 설명해놨다. 문제가 이해가 되고 나서 든 생각은 이렇다. 입력 크기에 맞게 메모리 할당 받은 뒤 하나씩 입력받는다. 입력받은 수가 0이면 이전에 있던 수를 0으로 만들고 그 인덱스로 되돌아간다. 이 작업이 끝나면 0부터 마지막 인덱스까지 수를 다 더하고 출력한다. 12345678910111213141516171819202122232425#include int main(){ int num; int *a; int j=-1; int sum=0; scanf("%d",&num); a = (int *)malloc(sizeof(int)*num); for(i..
1476)날짜 계산 https://www.acmicpc.net/problem/1476 이 문제를 읽고 비슷한 문제를 얼핏 떠올랐다. 그 문제는 최대공약수로 풀어내야 했는데 더 생각하길 그만뒀다. 제일 쉬운 방법은 E=0,S=0,M=0부터 1씩 올려가며 입력으로 주어진 E,S,M과 비교해보는 것이다. 123456789101112131415161718#include int main(){ int userE, userS, userM; int E=0,S=0,M=0; int year=0; scanf("%d %d %d",&userE,&userS,&userM); while(!(E==userE && S==userS && M==userM)){ E++; S++; M++; year++; if(E>15) E=1; if(S>28) S=1; if(M..
10799)쇠막대기 https://www.acmicpc.net/problem/10799 정답률 60% 넘는 게 쉬워 보여서 얘를 골랐다. 근데 완전 어려웠다. 어떻게 접근해야 할 지 몰라서 계속 헤멨던 것같다. 몇 가지 접근을 시도했는데 성공한 접근 방법의 핵심은 레이저 하나는 막대기를 같은 갯수로 분할한다는 점이다. 그림에서 보는 것처럼 레이저는 하나의 막대기를 2 개로 분할한다. 두 개의 막대기 위에 레이저가 있으면 레이저는 총 4개로 분할한다. 나는 레이저가 막대기를 분할할 때 레이저 앞 구간과 레이저 뒷 구간으로 바라봤다. 막대기 갯수를 세다가 레이저를 만났을 때 그 갯수를 저장한다. 그 갯수가 곧 레이저에 앞 구간의 막대기 갯수이다. 문제는 레이저가 두 개 이상이 되는 경우이다. 레이저에 의해 분할 되는 구간을 다..
2941)크로아티아 알파벳 https://www.acmicpc.net/problem/2941 크로아티아 알파벳이 두 개 또는 세 개의 알파벳으로 표현된다. 입력으로 주어지는 문자열은 크로아티아 알파벳과 알파벳이 섞여있을 수 있다. 크로아티아 알파벳과 알파벳 수를 세어 그 수를 출력해야 한다. 문자열 비교 알고리즘에서 점프 테이블의 용도가 다 비교하지 않고 건너뛰는 데서 약간의 아이디어를 얻었다. 예를 들어 문자열을 차례로 접근하다 'c'를 만나고 그 다음 문자가 '='이거나 '-'이면 1칸 건너 뛴다. 크로아티아 알파벳을 먼저 검사한 뒤 '='이거나 '-'인 경우를 제외한 알파벳을 세면 된다. 12345678910111213141516171819202122232425262728293031323334353637383940414243..
2902)KMP는 왜 KMP일까? https://www.acmicpc.net/problem/2902 문제 읽다가 피식했다. 이런 문제 너무 좋다 ㅎㅎ. 문제에서 제시하는 입력은 항상 Asdas-Dweas-Vasda 꼴이다. 하이폰으로 구분되는 단어들의 약자만 따서 만든 이니셜을 출력하면 된다. 항상 첫 단어는 하이폰 뒤에 있지 않기 때문에 반복문을 실행하기 전 첫 단어의 첫 문자를 먼저 출력해야 한다. 그 뒤 문자열에 하나씩 접근하면서 하이폰 뒤의 문자를 출력하면 된다. 12345678910111213#include int main() { char tempStr[101]; gets(tempStr); putchar(tempStr[0]); for (int i = 1; tempStr[i] != NULL;i++) { if (tempStr[i] ..
11365)!밀비 급일 https://www.acmicpc.net/problem/11365 주어진 문자열을 뒤집어서 출력하되 END를 만나면 종료해야 한다. 문자열을 역순으로 출력하기 위해 문자열의 끝이 어디인지 알아야 하는데 이를 알려면 문자열의 길이를 알아야 한다. C는 Java와 달리 문자열을 저장하는 String객체처럼 문자열에 관한 자세한 정보를 저장하는 객체가 없다. 문자열을 입력받으면 하나씩 세어 봐야 그 길이를 알 수 있다. END를 입력받고 프로그램을 종료할 때 ENDasd는 END가 아니라는 점을 주의해야 한다. 문자열의 인덱스 0번부터 2번까지 END인지 검사하는 코드를 넣는 것은 위와 같은 이유 때문에 문제가 있다. END와 일치했다고 해서 ENDasd가 END인 것은 아니기 때문이다. 또한 END인 경우..
11721)열 개 씩 끊어 출력하기 https://www.acmicpc.net/problem/11721 요즘 쉽다 생각하는 문제만 골라서 연습하려는데 자꾸 틀린다. 막상 이유를 알고나니 별 것 아니라는 게 참.. ㅎㅎ 이 문제는 최대 길이가 100인 문자열을 입력받고 10개씩 끊어 출력하는 문제다. C언어를 사용하면 주의해야할 점이 문자열의 끝을 구분하기 위해 NULL을 사용한다는 점이다. 길이가 100인 문자열을 저장한다면 NULL까지 101개의 문자형 배열을 선언해야 한다. 그뿐만 아니라 10개씩 끊어 출력할 때 NULL이 출력되지 않게 주의해야 한다. 문자열의 각 문자에 접근할 때 즐겨쓰는 신박한 코드가 있는데 아래 소스는 이를 반영했다. 123456789101112131415#include int main() { char tempC..