문제

지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M×N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8×8 크기의 체스판으로 만들려고 한다.

체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.

보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8×8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하시오.

 

입력

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

 

출력

첫째 줄에 지민이가 다시 칠해야 하는 정사각형 개수의 최솟값을 출력한다.


코드

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int N = sc.nextInt();
		int M = sc.nextInt();

		int[][] array = new int[50][50];

		// 1.  배열 입력
		for (int i = 0; i < N; i++) {
			String s = sc.next();
			for (int j = 0; j < M; j++) {
				if (s.charAt(j) == 'W') {
					array[i][j] = 1;
				} else {
					array[i][j] = 2;
				}

			}
		}
		
		// 2. 체스 정답 입력
		int[][] answer1 = new int[8][8];
		int[][] answer2 = new int[8][8];

		int[] pattern1 = { 1, 2, 1, 2, 1, 2, 1, 2 };
		int[] pattern2 = { 2, 1, 2, 1, 2, 1, 2, 1 };

		for (int i = 0; i < 8; i++) {
			if (i % 2 == 0) { // 짝수번째 인덱스
				answer1[i] = pattern1;
				answer2[i] = pattern2;
			} else {
				answer1[i] = pattern2;
				answer2[i] = pattern1;
			}
		}

		// 3. 체스판 찾기
		
		int row = N-7;
		int col = M-7;
		int mini = 64;
		
		for(int k = 0; k < row; k++) {
			for(int p = 0; p < col; p++) {
				
				int sum1 = 0;
				int sum2 = 0;
				for (int i = 0; i < 8; i++) {
					for (int j = 0; j < 8; j++) {
						if (array[i+k][j+p] != answer1[i][j]) {
							sum1 += 1;
							
						}
						if(array[i+k][j+p] != answer2[i][j]) {
							sum2 += 1;
						}
					}
				}
				int temp = Math.min(sum1, sum2);
				mini = Math.min(mini, temp);
			}
			
		}

		System.out.println(mini);

	}
}

 

풀이

1.  배열 입력

이 부분은 말 그대로 보드를 입력받는 부분이다. 이 코드 위에 N과 M을 입력받는 부분도 있다.

sc.next()를 이용해서 한 줄을 s에 저장하고 W면 1로, B면 2로 array에 저장해주었다.

 

2.  체스 정답 입력

이 문제는 무조건 확인할 때 8x8로 확인하고, 체스판이 될 수 있는 경우의 수가 2가지(맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우)이기 때문에 정답이 될 수 있는 경우를 answer1과 answer2로 나누어 저장해주었다.

즉 answer1은 아래와 같고, answer2는 맨 왼쪽 위 칸이 2로 시작할 것이다.

1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1
1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1
1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1
1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1

이렇게 저장한 answer1과 answer2를 가지고 입력받은 보드 위에 돌리면서 비교해 서로 다른 숫자의 개수를 세고 최솟값을 출력한다.

 

3. 체스판 찾기

만약 주어진 보드가 10x10 크기라면 8x8 크기인 answer1이 몇 개 돌릴 수 있을까?

간단하게 0~9까지 총 10칸이 있다고 생각하면 0~7, 1~8, 2~9 총 3개의 8칸을 돌릴 수 있다.

즉 10x10 크기로 생각하면 3 x 3 = 9 개의 체스판을 확인하게 된다.

만약 11x11이라면? 4x4 = 16 개의 체스판을 확인하게 된다. (이때 체스판은 문제에서 8x8로 자른다고 명시되어있다)

여기서 규칙을 알 수 있다. (주어진 보드 길이의 row - 3 ) x (주어진 보드 길이의 col - 3) 만큼의 체스판을 확인한다는 사실이다. 

주어진 보드판이 10x10이면 배열로 생각했을 때 [0][0]부터 [9][9]까지 존재한다. 

따라서 8x8인 answer1과 answer2와 보드를 8x8로 잘라서 비교하고, 틀린 것의 개수를 비교할 때마다 구해서 제일 작은 값을 출력한다. 10x10 보드를 8x8로 자른다면 위에 구했듯이 총 9번을 비교하게 될 것이다. 

[0][0]~[7][7]을 시작으로 [2][2]~[9][9]까지 이동할 것이다. (맨 왼쪽 위 ~ 맨 오른쪽 아래)

k와 p가 전체 8x8을 이동시키는 for문이 되고, i와 j가 8x8을 직접 탐색하는 for문이 된다.

i와 j의 이중 포문 안에서는 보드와 answer1을 비교해 값이 다르면 sum1에 1을 더해주고, 보드와 answer2를 비교해 값이 다르면 sum2에 1을 더해준다. 값이 다르다는 건 정답인 answer와 다른 부분인 것이고, 즉 체스판이 되기 위해서 다시 칠해야 하는 부분인 것이다. array에서 k과 p를 더해주는 이유는 처음에 입력받은 보드를 8x8 크기로 잘라줄 때 이동시키기 위해서이다.

이때 sum1과 sum2는 8x8 비교를 한 번 할 때마다 구하므로 i 포문 위에서 0으로 계속 초기화시켜준다. 한 번의 비교 후에는 최솟값을 구해준다. Math.min 함수는 괄호 안의 두 값 중 최솟값을 반환해준다. mini가 64인 이유는 최대로 체스판을 만들기 위해 색칠하는 횟수가 64이기 때문이다. 

728x90

wow 드디어 매일 입으로만 받는다고 했던 퍼스널 컬러를 받고 왔다. 윤주씨가 함께 해주셨다. (매우 영광)

 

어쨌든 결과는 가을 soft(뮤트) 톤이었다. 아주 놀라운 결과였다. 난 여름 쿨이고 싶었다. 그러나 여름 soft도 같이 쓸 수 있다고 하셔서 좋았다.

애초에 내 톤이 좀 애매한 톤인 것 같았다. 처음에 웜, 쿨인지 먼저 봐주셨는데 한참 측정하다가 다른 걸로 넘어가신 걸 보면 애매했나 보다.

 

best는 가을 soft이지만 여름 soft, 가을 dull, 여기에 어두운 색으로 염색하면 봄 vivid도 좋다고 하셨다. 

화장품은 갈아엎지 않아도 되지만 옷이 아주 심각하다. 사실 원래 옷이 없어서 좋게 생각하기로 했다.

곧 봄이 오는데 봄 옷부터 차근차근 모아야겠다.

 

오늘 간 곳은 '컬러뷰'라는 곳으로 아주 만족스러웠다. 2명이서 14만 원 내고 가서 처음에는 너무 비싸다고 생각했는데 받고 나서는 이해가 되는 가격이었다. 아래 순서대로 진행했는데 2시간 살짝 더 걸렸다. 

 

1. 톤이 무엇인지 천을 대가며 판단 (웜 or 쿨, 명도, 채도)

-> 톤에 맞는 컬러가 그려있는 카드와 직접 결과를 손으로 써주신 카드 2개를 주신다.

2. 컬러뷰에 있는 화장품 웜인지 쿨인지 판단해보기

3. 가져온 화장품 판단하기 

4. 화장품 추천 (피부 메이크업도 살짝 해주심)

 

끝나고 나서도 모르는 게 있으면 카톡 하라고 하시고 정말 친절하셨다. 실제로 카톡 해서 오늘 쓴 퍼프 뭐냐고 여쭤봤다. 쿠팡에 있는 키메라제이 삼각 퍼프라고 하셔서 당장 구매했다. 파운데이션이 촉촉하게 스며드는 게 최고였다...

오늘 추천해주신 파운데이션 성분이 안 맞을까 봐 다른 파운데이션도 추천해주실 수 있냐고 물어봤는데, 여러 개 추천해주시곤 다음 날 색상 비교한 것도 보내주신다고 하셨다. 정말 쏘 스위트 하셨다.. 이 가격 내고할 만하다.

 

다들 퍼스널 컬러를 안 받아봤다면 강추강추강추한다.

728x90

'Diary' 카테고리의 다른 글

코드트리 쌀 기부 & solved.ac 현황  (0) 2022.05.07
Solved.ac 새싹 4단계 달성😊  (0) 2022.04.25
1월 21일 일기  (0) 2022.01.22
1월 20일 일기  (0) 2022.01.20
1월 3일 할 일 & 결과  (0) 2022.01.02

1. 완료한 것

- figma로 디자인

- notion 정리

- start page 완성

- start page에서 버튼 누르면 로그인 페이지로 이동

 

2. 코드

페이지에서 페이지간 이동을 하는 방법을 구글링을 통해 찾아봤었는데 class component로 쓰여진 글이 많아서 function component로 바꿔서 사용해보았다. (사실 function component가 훨씬 익숙하다,,)

StartPage.js에서 시작하기 버튼을 누르면 Login.js에서 넘어갈 수 있도록 구현했다.

 

① App.js

- 설치할 것

npm install @react-navigation/native

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
/*App.js*/
import React, { Component } from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import StartScreen from "./src/StartPage";
import LoginScreen from "./src/Login";

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
        // header를 감춘다
          options={{ headerShown: false }}
          name="StartPage"
          component={StartScreen}
        />
        <Stack.Screen
          options={{ headerShown: false }}
          name="Login"
          component={LoginScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

코드의 순서에 따라 달라진다. 위에 있는 page가 가장 먼저 실행된다.

 

② StartPage.js

import { StatusBar } from "expo-status-bar";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Dimensions,
} from "react-native";
import { Image } from "react-native";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function StartPage({ navigation }) {
  return (
    <View>
      <Text>CHERISH PET!</Text>
      <StatusBar style="auto" />
      <View>
        <TouchableOpacity onPress={() => navigation.navigate("Login")}>
          <Text>시작하기</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

간소화한 코드로, 오늘 완성한 코드와는 다르다. TouchableOpacity의 onPress 속성으로 눌렀을 때 "Login" 페이지로 넘어가도록 했다.

 

③ Login.js

import { StatusBar } from "expo-status-bar";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Dimensions,
} from "react-native";
import { Image } from "react-native";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function Login({ navigation }) {
  return (
    <View>
      <StatusBar style="auto" />
      <View>
        <Text>CHERISH PET!</Text>
    </View>
  );
}

 

※ 참고한 사이트

https://dlee0129.tistory.com/15

 

 

728x90
ERROR: JAVA_HOME is set to an invalid directory: C:\Program Files (x86)\Java\jdk-11.0.2+9;

라는 오류가 나서 구글링을 해봤더니 역시 stackoverflow에서 답을 찾을 수 있었다.

바로 ;을 JAVA_HOME에서 제거하는 것이었다.

 

따라서 시스템 환경 변수를 바꿔주어야하는데 시스템 환경 변수에 들어가는 방법은 2가지가 있다.

 

방법 1.

① 윈도우 검색창에 '시스템 환경 변수 편집' 이라고 친다.

② 오른쪽 아래에 있는 환경변수 버튼을 누른다.

③ 시스템 변수의 JAVA_HOME을 찾고 편집버튼을 누른 뒤 경로를 아래와 같이 ;를 제거한 경로로 바꿔준다.

 

방법 2.

① 제어판 > 시스템에 들어가서 아래로 스크롤하고 '이 PC의 이름바꾸기(고급)'을 누른다.

② 방법 1의 ②와 같다

③ 방법 1의 ③과 같다

 

※ 참고 사이트

https://stackoverflow.com/questions/45182717/java-home-is-set-to-an-invalid-directory

 

728x90

'기타' 카테고리의 다른 글

gitlab에 있는 프로젝트 github에 가져오기  (0) 2023.11.28
vscode 단축키 모음  (0) 2022.02.09
python 가상환경 설정 및 실행 (window, cmd 기준)  (0) 2022.02.05
git 명령어 모음  (0) 2022.02.01

※ Oracle Database 기준입니다.

 

1. EMP 테이블에 1개의 새로운 칼럼을 추가하는 SQL문을 작성하고 실행 후, 테이블의 구조를 출력

ALTER TABLE EMP
ADD (ADDRESS VARCHAR2(80));
DESC EMP;

EMP 테이블에 이름이 ADDRESS이고 유형이 VARCHAR2(80)인 칼럼이 추가된다.

DESC EMP를 통해 EMP 테이블의 구조를 출력할 수 있다.

DESC는 description의 약자이며 description으로도 출력이 가능하다.

 

2. EMP 테이블에 존재하는 칼럼 하나에 대해 MODIFY를 실행하는 SQL문을 작성하고 실행 후, 테이블의 구조를 출력

ALTER TABLE EMP
MODIFY (ENAME VARCHAR2(11) DEFAULT 'JOHN DOE' NOT NULL);
DESC EMP;

기존에 존재하던 칼럼인 ENAME의 유형을 VARCHAR2(11), NOT NULL, 디폴트 value가 'JOHN DOE'가 되도록 바꾸어준다.

이때 NOT NULL이란 ENAME에 NULL이 들어오면 안 된다는 의미로, 빈 값이 들어오거나 NULL이 직접 입력되면 오류가 난다. 

DEFAULT의 의미는 사용자가 아무것도 입력하지 않은 빈 값이 들어올 때 들어갈 디폴트 값을 의미한다. 사용자가 NULL을 입력하게 되면 디폴트 value가 들어가지 않고 NULL이 그대로 들어간다.

 

3. EMP 테이블의 특정 칼럼 1개의 이름을 바꾸는 SQL문을 작성하고 실행 후, 테이블의 구조를 출력

ALTER TABLE EMP
RENAME COLUMN JOB TO WORK;
DESC EMP;

현재 존재하는 칼럼인 JOB의 이름을 WORK로 변경한다. RENAME을 사용해 쿼리문을 작성하면 된다.

 

4. EMP 테이블의 칼럼 1개에 대해 새로운 제약조건을 생성하는 SQL문을 작성

ALTER TABLE EMP
ADD CONSTRAINT EMP_ADDRESS UNQUE(ADDRESS);

 

ADD CONSTRAINT를 통해 CONSTRAINT의 이름이 EMP_ADDRESS이고 CONSTRAINT type이 unique인 제약조건을 생성한다.

이때 unique란 중복 값이 들어갈 수 없도록 하는 것이다.

728x90

+ Recent posts