hyunjin

[함수 - 한수(1065)] C++ , sync_with_stido , endl > \n 본문

알고리즘 연습/백준

[함수 - 한수(1065)] C++ , sync_with_stido , endl > \n

_h.j 2020. 8. 13. 16:15
728x90

백준/함수/한수(1065) 문제 바로 가기

 

채점 현황

[간단 문제 설명]

자연수의 각 자리가 등차 수열을 이룰 때 그 수를 한수라 한다.

자연수 N(<=1000)이 주어졌을 때 N이하의 한수 개수를 출력해라.

 

 

[첫 번째 소스 코드(c++)]

#include <iostream>
#include <vector>

using namespace std;

bool isHanNum(int num) {
	if (num <= 99 && num >= 1) return true;
	int d1 = (num % 100) / 10 - num % 10;
	num /= 10;
	while ( num >= 10) {	
		int d2 = (num%100)/10 - num % 10;
		num /= 10;
		if (d1 != d2) return false;
		d1 = d2;
	}
	return true;
}

int main(void) {
	int N = 0,res=0;
	cin >> N;
	for (int i = 1; i <= N; i++)
		if (isHanNum(i))
			res++;
	cout << res;
	return 0;
}

 

[풀이 전략]

1.두 자리 수 까진 비교할 다른 자리가 없기 때문에 바로 한수가 되므로 바로 리턴

2. 세 자리 수 부터는 일의 자리와 그 위의 자리 숫자 부터 공차 비교

3. 사실 입력 값 최대가 10000이므로 세 자리 숫자만 한수인지 확인하면 된다.

   즉 공차는 2개가 생기고 그것들만 비교하면 되는 것이다.

4. 하지만 10000 이상의 수도 들어올 수 있다는 가정하에 풀었다.

 

[예상 수행 시간]

 

 

 

 

[아쉬운 점]

-더 효율적인 코드가 있을까?

-main에서 N이 99 이하라면 바로 N을 리턴하고

100이상인 경우는 100부터 for문을 돌려 리턴 전에 +99 해주면 시간이 조금 덜 걸린다.

 

[다른 사람 풀이]

-더 효율적인 코드인지는 모르지만 정리된 이상적인 코드를 발견

-입력값이 최대 10000이므로 어차피 비교해야할 공차는 2개니까 각 자리 수를 나눠놓은 다음에 공차 비교

#include <iostream>
#define endl "\n"
using namespace std;

int N;

void Input() {
	cin >> N;
}

void Solution() {
	int Ans = 0;

	if (N <= 99) Ans = N;
	else {
		Ans = 99;
		for (int i = 100; i <= N; i++) {
			if (i == 1000) break;
			int num[4] = { 0, };
			int tmp = i, index=0;
			while (tmp > 0) {
				num[index] = tmp % 10;
				tmp /= 10;
				index++;
			}

			if (num[1] - num[0] == num[2] - num[1])
				Ans++;
		}

	}
	cout << Ans << endl;
}

void Solve() {
	Input();
	Solution();
}

int main(void){
	
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	Solve();
	return 0;
}

 

 

 

[배운 내용]

1. ios_base::sync_with_stido(bool sync) 

C++ 표준 스트림들이 C표준 스트림들과 각각의 입출력 연산 후에 동기화 여부 설정
false : C 표준 stream과 C++ 표준 stream의 동기화를 끊는다.
리턴값 : 함수 호출하기 전 이전의 동기화 상태

기본적으로, 모든 표준 stream들은 동기화 되어있다.

동기화된 C++ stream들이 자신의 버퍼 대신 C++ stream의 입출력 연산들이

이에 대응되는 C stream 버퍼를 사용

 C와 C++의 입출력 방식을 자유롭게 혼용 가능

 

동기화를 끊는다면, C++ stream은 독립적인 버퍼를 갖게 되어

C와 C++의 입출력 방식 혼용하여 쓰는 것이 위험 => 출력 순서를 보장하지 않기 때문

 

또한 동기화된 C++ stream들은 thread-safe (안정성 보장)한다.

여러 쓰레드에서 각각 출력 연산을 수행할 수 있지만, 경쟁 상태(race condition) 발생하지 않음.

(  다른 thread의 output이 동시에 액세스해도 충돌하지 않는다.)

 

동기화를 끊으면 사용하는 버퍼의 수가 줄어들어 실행속도 자체는 크게 향상된다.

 

더 자세한 내용은 여기로

 

 

참고 사이트,출처

다른 사람 풀이 바로가기 

100이상 +99 해주는 풀이 바로가기

sync_with_stdio 설명 바로가기

 

 

 

728x90