#작성 코드

#include <iostream>
#include <cstdio>
#include <algorithm>

long long int num;
int digit[10];

bool comp(int a, int b){
	return a>b;
}
int main(){
	scanf("%lld", &num);
	if( num > 1000000000 ) return 0;
	// 입력받은 수의 자리수를 계산. 
	int t=1, digits=1;
	while( num >= t ){
		t*=10;
		digits++;	
	}
	// 각 자리수를 digit배열에 하나씩 저장. 
	for(int i=0; i<10; i++){
		int tmp = num%10;
		digit[i] = tmp;
		num/=10;
	}
	// digit배열의 내용을 내림차순으로 정렬. 
	std::sort(digit, digit+10, comp);
	// 자리수만큼 digit배열의 내용을 출력한다. 
	for(int i=0; i<digits-1; i++){
		printf("%d", digit[i]);
	}
	return 0;
}

##

'BOJ' 카테고리의 다른 글

BOJ 11651번 :: 좌표 정렬하기2  (0) 2019.11.24
BOJ 11650번 :: 좌표 정렬하기  (0) 2019.11.24
BOJ 2108번 :: 통계학  (0) 2019.11.23
BOJ 1436번 :: 영화감독 숌  (0) 2019.11.23
BOJ 1018번 :: 체스판 다시 칠하기  (0) 2019.11.21

#작성 코드

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int N;
int arr[500000];

bool comp(pair<int, int> a, pair<int, int> b){
	if( a.second == b.second ){
		return a.first < b.first;
	}
	else
		return a.second>b.second;
}

int findmaxcount(int *arr, int N){
	vector< pair<int, int> > count;		// 값, 빈도 저장할 배열 0으로 초기화 
	for(int i=0; i<N; i++){
		if(count.empty()){
			count.push_back(pair<int, int>(arr[i], 1));
			continue;	
		}
		if(count.back().first == arr[i]){		// arr이 순서대로 정렬되어있으므로 가능하다. 
			pair<int, int> tmp = count.back();
			tmp.second++;
			count.pop_back();
			count.push_back(tmp);
		}
		else{
			count.push_back(pair<int, int>(arr[i], 1));
		}
	}
	// '1순위 : 빈도, 2순위 : 값 작은 순서'로 정렬
	sort(count.begin(), count.end(), comp );
	
	if( count[0].second == count[1].second){
		return count[1].first;	// 빈도수 같으면 값 더 큰것 
	}
	else{
		return count[0].first;	// 빈도수 더 큰것. 
	}
}
int main(){
	scanf("%d", &N);
	double sum=0;
	for(int i=0; i<N; i++){
		scanf("%d", &arr[i]);
		sum+=arr[i];
	}
	sort(arr, arr+N);		// arr 배열을 오름차순으로 정렬 
	
	int maxcount = findmaxcount(arr, N);
	printf("%d\n", (int)floor(sum/N+0.5));	// 산술평균 출력(소수점이하 첫째자리에서 반올림) 
	printf("%d\n", arr[N/2]);			// 중앙값 출력
	printf("%d\n", maxcount);			// 최빈값 출력
	printf("%d\n", arr[N-1]-arr[0]);	// 범위 출력 
	return 0; 
} 

##

최빈값을 구할 때, 2차원 count배열을 만들어서 [값][0]에 값을 저장하고, [값][1]에 빈도수를 저장하려고 했지만 음수 값 케이스를 생각하지 못했다. 음수는 배열의 인덱스로 사용할 수 없기 때문에  => vector와 pair를 사용해서 (값, 빈도수)를 저장했다.

의외로 산술평균을 출력하는 곳에서 오류가 발생했다.

처음 시도한 코드는 (int)( (sum/N)+0.5 )를 10진수로 출력하는것이었는데 음수의 경우 원하는 결과가 나오지 않았다.

=> ( (sum/N) + 0.5 )의 결과에 '버림'연산(floor)을 진행한 후에 int형으로 출력하였다.

'BOJ' 카테고리의 다른 글

BOJ 11650번 :: 좌표 정렬하기  (0) 2019.11.24
BOJ 1427번 :: 소트인사이드  (0) 2019.11.23
BOJ 1436번 :: 영화감독 숌  (0) 2019.11.23
BOJ 1018번 :: 체스판 다시 칠하기  (0) 2019.11.21
BOJ 7568번 :: 덩치  (0) 2019.11.21

#작성 코드

#include <cstdio>

int main(){
	int N;
	scanf("%d", &N);		// 몇 번째 영화의 제목이 궁금한지 
	
	int cnt=1, number=666;	// 666은 가장 작은 종말의수  
	int a, b, c;	// 연속된 세 자리의 자릿수를 저장할 변수 
	while(1){
		if( cnt == N ) break;
		number++;
		int numcopy = number;
		int serial = 0;
		while( numcopy ){
			int temp = numcopy%10;	// 일의 자리수부터 차례로 비교 
			if( temp == 6 ){
				serial++;
			}
			else if( serial<3 ){	// 그 다음 수가 6이 아니면 serial 초기화 
				serial = 0;			// 6이 연속으로 안나왔으므로! 
			}
			numcopy/=10;			// 그 다음 자리수가 일의 자리수로 오도록 
		}							// 현재 number의 모든 자리수 비교 완료 
		if( serial >= 3 ){			// 6이 세 번 이상 연속으로 등장 
			cnt++;
		} 
	}
	printf("%d\n", number);
	return 0;
}

##

처음엔 각 자리수의 비교를 아래와 같이 진행했었는데 연산의 횟수가 불필요하게 많았던 것 같다.

#include <cstdio>

int main(){
	int N;
	scanf("%d", &N);		// 몇 번째 영화의 제목이 궁금한지 
	
	int cnt=0, number=665;	// 666은 가장 작은 종말의수  
	int a, b, c;	// 연속된 세 자리의 자릿수를 저장할 변수 
	 
	while(cnt<N){
		int t=100;
		do{
			a = number/t;
			b = (number%t)/(t/10);
			c = number%(t/10);
			if( a==6 && b==6 && c==6 ){
				cnt++;
			}else{
				t*=10;
			}
		}while( t<number );
		number++;
	}
	printf("%d", number-1);
	return 0;
}

각 자리수를 작은 자릿수부터 비교할 때, 아래와같이 연산하면 연산횟수를 많이 줄일 수 있음을 알았다.

int temp = number%10;

...

number /= 10;

'BOJ' 카테고리의 다른 글

BOJ 1427번 :: 소트인사이드  (0) 2019.11.23
BOJ 2108번 :: 통계학  (0) 2019.11.23
BOJ 1018번 :: 체스판 다시 칠하기  (0) 2019.11.21
BOJ 7568번 :: 덩치  (0) 2019.11.21
BOJ 2231번 :: 분해합  (0) 2019.11.21

#문제

https://www.acmicpc.net/problem/1018

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

 

#작성 코드

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

int min(int a, int b){
	return a<b?a:b;
}

int calCnt(const char board[52][52], int i, int j) {
	int cnt = 0;					// 새로 칠해야 할 칸의 개수 
	for (int p = 0; p<8; p++) {
		for (int q = 0; q<8; q++) {
			if( p%2==0 ){
				if( q%2==0 ){
					if( 'B' == board[i+p][j+q])
						cnt++;
				}
				else{
					if( 'W' == board[i+p][j+q])
						cnt++;
				}
			}
			else{
				if( q%2==0 ){
					if( 'W' == board[i+p][j+q])
						cnt++;
				}
				else{
					if( 'B' == board[i+p][j+q])
					cnt++;
				}
			}
		}
	}
	return cnt;
}

char board[52][52];

int main() {
	int N, M;
	cin>>N>>M;

	// 주어진 보드의 상태 입력!!! 
	for (int i = 1; i<=N; i++) {
		for(int j=1; j<=M; j++)
			cin>>board[i][j];
	}

	int Min = 3000;	// 새로 칠해야하는 칸의 최소 개수
	for (int i = 1; i<=N-7; i++) {
		for (int j = 1; j<=M-7; j++) {
			int cnt = calCnt(board, i, j);
			cnt = min(cnt, 64-cnt);
			Min = min(Min, cnt);
		}
	}
	printf("%d\n", Min);
	return 0;
}

2020/02/06 review

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;
 
int answer=1000000;
char chess[50][50];
 
int main(){
    int size1, size2;
    cin>>size1>>size2;
    for(int i=0; i<size1; i++){
        for(int j=0; j<size2; j++){
            cin>>chess[i][j];
        }
    }
 
    for(int x=0; x<size1-7; x++){
        for(int y=0; y<size2-7; y++){
            int cnt=0;
            for(int sizex=0; sizex<8; sizex++){
                for(int sizey=0; sizey<8; sizey++){
                    if( x+sizex >= size1 || y+sizey >=size2 )
                        continue;
                        
                    if( (x+y+sizex+sizey)%2==0 ){
                        if( chess[x+sizex][y+sizey]=='W' ){
                            cnt++;
                        }
                    }
                    else if( (x+y+sizex+sizey)%2!=0 ){
                        if( chess[x+sizex][y+sizey]=='B'){
                            cnt++;
                        }
                    }
                }
            }
            cnt = min(cnt, 64-cnt);
            answer = min(answer, cnt);
        }
    }
    cout<<answer<<'\n';
    return 0;
cs

 

##

https://www.acmicpc.net/board/view/38392에서 반례를 찾아서 코드를 수정했다.

이상하게도, 당연히 주어진 체스판의 첫 번째 칸을 기준으로 8*8만큼을 비교해야 한다고 생각했다.

8*8만큼 자르는 것을 기준으로 첫 번째 칸과 비교해서 고쳐야 할 칸 수(cnt)를 세었을 때

흰색으로 시작하는 값을 기준으로 생각했다면, 검은색 칸으로 시작할 때는 64-cnt 만큼만 칸을 고쳐주면 된다.

고쳐야 할 칸의 최솟값은 흰색으로 시작하는 보드, 검은색으로 시작하는 보드 두 케이스 모두를 고려한 값 중에서 더 작은 값을 선택하면 되는 것이었다.

 

'BOJ' 카테고리의 다른 글

BOJ 2108번 :: 통계학  (0) 2019.11.23
BOJ 1436번 :: 영화감독 숌  (0) 2019.11.23
BOJ 7568번 :: 덩치  (0) 2019.11.21
BOJ 2231번 :: 분해합  (0) 2019.11.21
BOJ 2798번 :: 블랙잭  (0) 2019.11.21

#작성 코드

#include <iostream>
#include <cstdio> 
#include <vector>
#include <utility>
using namespace std;

int main(){
	int N;
	scanf("%d", &N);
	vector< pair<int, int> > v;
	for(int n=0; n<N; n++){
		int x, y;
		scanf("%d %d", &x, &y);
		v.push_back(pair<int, int>(x, y));
	}
	int *grade = new int[N];
	for(int i=0; i<N; i++) grade[i]=1;		// grade배열을 모두 0으로 초기화 
	for(int i=0; i<N-1; i++){
		for(int j=i+1; j<N; j++){
			if( v[i].first > v[j].first && v[i].second > v[j].second ){
				grade[j]++;
			}
			else if(v[i].first < v[j].first && v[i].second < v[j].second){
				grade[i]++;
			}	
		}
	}
	for(int i=0 ;i<N; i++){
		printf("%d ", grade[i]);
	}
	return 0;
}

##

처음으로 vector와 pair를 스스로 사용해보았다!

'BOJ' 카테고리의 다른 글

BOJ 1436번 :: 영화감독 숌  (0) 2019.11.23
BOJ 1018번 :: 체스판 다시 칠하기  (0) 2019.11.21
BOJ 2231번 :: 분해합  (0) 2019.11.21
BOJ 2798번 :: 블랙잭  (0) 2019.11.21
BOJ 11729번 :: 하노이 탑 이동 순서  (0) 2019.11.20

# 문제

https://www.acmicpc.net/problem/2231

 

2231번: 분해합

문제 어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다. 자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그

www.acmicpc.net

 

#작성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
int main(){
    int n;
    cin>>n;
    
    for(int i=1; i<=n; i++){
        int tmp=i;
        int gen=tmp;
        while( tmp ){
            gen+=tmp%10;
            tmp/=10;
        }
        if( gen==n ){
            cout<<i<<'\n';
            return 0;
        }
    }
    
    // 생성자가 존재하지 않으면 0을 출력해야한다. 
    cout<<"0\n";
    return 0;
cs

##

2020/02/03 update

'BOJ' 카테고리의 다른 글

BOJ 1018번 :: 체스판 다시 칠하기  (0) 2019.11.21
BOJ 7568번 :: 덩치  (0) 2019.11.21
BOJ 2798번 :: 블랙잭  (0) 2019.11.21
BOJ 11729번 :: 하노이 탑 이동 순서  (0) 2019.11.20
BOJ 10870번 :: 피보나치 수 5  (0) 2019.11.20

+ Recent posts