본문 바로가기

CodingTest Exam/[C++] Algorithm Study

30. 3의 개수는?(large) (it 취업을 위한 알고리즘 문제풀이 입문 (with C/C++) : 코딩테스트 대비) ★★★★☆

#include<stdio.h>
#include<vector>

using namespace std;
int main()
{
	int n;
	scanf("%d", &n);
	
	int lt = 1;
	int k = 1;
	int rt, cur = 0;
	int count = 0;
	
	while(lt != 0)
	{
		lt = n / (k * 10);
		cur = (n / k) % 10;
		rt = n % k;
		
		if(cur > 3)
		{
			count += (lt+1) * k;
		}
		else if(cur == 3)
		{
			count += (lt * k) + (rt + 1);
		}
		else
		{
			count += lt * k;
		}
		
		k *= 10;
	}
	
	printf("%d", count);
	return 0;
}

1. 포인터를 활용하여 풀면 아주 쉽게 풀 수 있는 문제이다.

포인터는 rt, lt, cur 총 3개를 활용한다. 포인터의 이동은 k를 활용한다.

5367을 예로 들겠다.

시작은 1의 자리 숫자인 7부터 시작한다.

ltcur의 왼쪽인 536을 가리키고, rtcur의 오른쪽인 0을 가리킨다.

                                                                                                                                                                cur   ↓

5 3 6 7

 

여기서 중요한데, cur이 3보다 큰지, 같은지, 작은지에 따라서 count 개수가 달라진다.

 

위 상황처럼 cur > 3 일 경우를 보면 0007 ~ 5363까지 3이 등장한다.

이는 (lt + 1) * k = (536+1) * 1 = 537개 로 계산할 수 있다.

lt + 1인 이유는 0007, 즉 7일 때 lt가 0이기 때문에 0~536개인 537개이다. k는 현재 cur의 자리수이다.

 

전체 카운트가 끝나면 k에 10을 곱해서 cur의 자리수를 한 단계 올려준다.

 

                                                                                                               cur   ↓

5 3 6 7

 

위 두 상황을 보면 lt, cur, rt 를 계산할 수 있는 식을 도출할 수 있다.

lt = n / (k * 10) = 5367 / (10 * 10) = 5367 / 100 = 53

cur = (n / k) % 10 = (5367 / 10) % 10 = 536 % 10 = 6

rt = n % k = 5367 % 10 = 7

 

위 상황과 동일하게 cur > 3 이므로

 (lt + 1) * k = (53+1) * 10 = 540개 로 계산할 수 있다.

 

                                                               cur   ↓

5 3 6 7

cur = 3 이므로

 0300 ~ 5367 까지 3이 등장한다.

3을 빼고 보면 000~567까지 등장한다는 의미이므로 568개이다.

(lt * k) + (rt+ 1) = (5 * 100) + (67 + 1) = 568개 

 

               cur   ↓

5 3 6 7

cur > 3 이므로

 (lt + 1) * k = (0+1) * 1000 = 1000

 

이후로 lt != 0 조건에서 false로 while문이 break 된다.

 

총 개수 = 537 + 540 + 568 + 1000 = 2645개