#작성 코드

#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

 

#작성 코드

#include <cstdio>

int main()
{
	int N, M;
	scanf("%d %d\n", &N, &M);
	int *cards = new int[N];
	for(int i=0; i<N; i++){
		scanf("%d", &cards[i]);
	}
	int max=0;
	for(int i=0; i<N; i++){
		for(int j=i+1; j<N; j++){
			for(int k=j+1; k<N; k++){
				int sum = cards[i]+cards[j]+cards[k];
				if( sum<=M && max < sum ){
					max = sum;
				}
			}
		}
	}
	printf("%d\n", max);
	return 0;
}

##

'BOJ' 카테고리의 다른 글

BOJ 7568번 :: 덩치  (0) 2019.11.21
BOJ 2231번 :: 분해합  (0) 2019.11.21
BOJ 11729번 :: 하노이 탑 이동 순서  (0) 2019.11.20
BOJ 10870번 :: 피보나치 수 5  (0) 2019.11.20
BOJ 10872번 :: 팩토리얼  (0) 2019.11.20

#작성 코드

#include <iostream>
#include <cstdio>

void hanoi(int from, int by, int to, int n){
	if( n <= 1 ){
		printf("%d %d\n", from, to);
		return;
	}
	else{
		hanoi(from, to, by, n-1);
		hanoi(from, by, to, 1);
		hanoi(by, from, to, n-1);
	}
}
int main(){
	int N;
	scanf("%d", &N);
	printf("%d\n", (1<<N)-1);
	hanoi(1, 2, 3, N);
	return 0;
}

##

 

'BOJ' 카테고리의 다른 글

BOJ 2231번 :: 분해합  (0) 2019.11.21
BOJ 2798번 :: 블랙잭  (0) 2019.11.21
BOJ 10870번 :: 피보나치 수 5  (0) 2019.11.20
BOJ 10872번 :: 팩토리얼  (0) 2019.11.20
BOJ 1002번 :: 터렛  (0) 2019.11.20

+ Recent posts