<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>hoonDEV</title>
    <link>https://hoondev.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 17 Apr 2026 03:23:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>훈개발자</managingEditor>
    <image>
      <title>hoonDEV</title>
      <url>https://tistory1.daumcdn.net/tistory/1943235/attach/7fe8af0a35334c6d95961d1e9ab07bf8</url>
      <link>https://hoondev.tistory.com</link>
    </image>
    <item>
      <title>Angular에서 Tailwind CSS 사용해보기</title>
      <link>https://hoondev.tistory.com/111</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;이 문서는 개발을 하면서 차차 채워나갈 예정입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;회사에서 Tailwind CSS를 도입하게 되면서, Tailwind CSS에 대해서 알아보기로 하였다.&lt;/p&gt;
&lt;h2&gt;Angular 프로젝트에 Tailwind CSS 도입하기&lt;/h2&gt;
&lt;p&gt;너무 감사하게도 &lt;code&gt;ng eject&lt;/code&gt;로 Webpack 설정을 바꾸지 않고, Angular 프로젝트에 Tailwind CSS를 도입할 수 있는 &lt;code&gt;ng-tailwindcss&lt;/code&gt;라는 좋은 CLI가 있다.&lt;/p&gt;
&lt;h3&gt;설치 방법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npm i ng-tailwindcss -g&lt;/code&gt; : 글로벌에 Angular 프로젝트에 Tailwind CSS를 도입할 수 있도록 도와주는 &lt;code&gt;ng-tailwindcss&lt;/code&gt;를 설치한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npm i tailwindcss -D&lt;/code&gt; : 해당 프로젝트에 &lt;code&gt;tailwindcss&lt;/code&gt; 라이브러리를 추가한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npx tailwind init&lt;/code&gt; : Tailwind CSS를 프로젝트에서 사용할 수 있도록 초기 파일을 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ngtx configure&lt;/code&gt; : &lt;code&gt;ng-tailwindcss&lt;/code&gt;가 해당 프로젝트의 Tailwind CSS를 관리할 수 있도록 하는 설정 파일을 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;touch src/tailwind.scss&lt;/code&gt; : Tailwind CSS는 이 파일에 있는 Utility들을 프로젝트가 실행되는 내내 감시(watch)하며 변동된 사항이 있을 경우 이를 스타일에 반영한다. 그러한 기능을 담당하는 &lt;code&gt;tailwind.scss&lt;/code&gt;를 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;사용 방법&lt;/h3&gt;
&lt;p&gt;처음 설치 과정이 끝나면 루트 폴더에 ng-tailwind.js가 생성된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;module.exports = {
  // Tailwind Paths
  configJS: &amp;#39;tailwind.config.js&amp;#39;,
  sourceCSS: &amp;#39;src/tailwind.scss&amp;#39;,
  outputCSS: &amp;#39;src/styles.scss&amp;#39;,
  // Sass
  sass: false,
  // PurgeCSS Settings
  purge: false,
  keyframes: false,
  fontFace: false,
  rejected: false,
  whitelist: [],
  whitelistPatterns: [],
  whitelistPatternsChildren: [],
  extensions: [
    &amp;#39;.ts&amp;#39;,
    &amp;#39;.html&amp;#39;,
    &amp;#39;.js&amp;#39;
  ],
  extractors: [],
  content: []
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;처음에는 &lt;code&gt;sourceCSS&lt;/code&gt;와 &lt;code&gt;outputCSS&lt;/code&gt;의 확장자가 모두 css로 되어 있을탠데, 우리는 SCSS를 사용하므로, 확장자를 모두 scss로 바꿔주었다.&lt;/p&gt;
&lt;p&gt;실제로 &lt;code&gt;src/tailwind.scss&lt;/code&gt;를 Tailwind가 프로젝트가 실행되는 동안 감시하며 Tailwind에서 정의된 Utility 스타일과 사용자가 정의한 Custom 스타일을 조합 및 생성하여 &lt;code&gt;src/styles.scss&lt;/code&gt;로 output된다. 이를 이용해 프로그램 전역에 적용하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/tailwind.scss&lt;/code&gt;에 아래와 같이 써줘서 Tailwind CSS를 시작한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;@tailwind base; @tailwind components; @tailwind utilities;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pre-flight&lt;/h2&gt;
&lt;p&gt;첫 번째 줄인 &lt;code&gt;@tailwind base&lt;/code&gt;는 Tailwind CSS에서 &lt;code&gt;Pre-flight&lt;/code&gt;라고 부른다.&lt;/p&gt;
&lt;p&gt;브라우저 간의 스타일 불일치를 줄이고, 브라우저의 제약 조건 내에서 스타일링을 쉽게 해주기 위해 Tailwind CSS에서 제공하는 &lt;strong&gt;기본 스타일 세트&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;거의 기본 스타일을 제거하여 커스터마이징을 쉽게 하도록 하는 역할을 하는 것 같다. 어차피 Tailwind CSS에서 제공하는 다양한 스타일링 유틸리티 들을 이용하면 되기 때문이다.&lt;/p&gt;
&lt;p&gt;@tailwind base을 적용할 경우 아래와 같은 스타일들이 &lt;code&gt;style.scss&lt;/code&gt;로 output된다.&lt;/p&gt;
&lt;h3&gt;제목, 인용 부호, 단락 등과 같은 요소에 기본 margin이 제거됩니다.&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;blockquote, dl, dd, h1, h2, h3, h4, h5, h6, figure, p, pre { margin: 0; }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;기본 설정된 margin으로 인해 스타일링에 있어서 실수를 줄이기 위함이라고 합니다.&lt;/p&gt;
&lt;h3&gt;제목(h1, h2..) 태그에 스타일이 없습니다.&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CSS에서 Type scale 스타일링에 문제가 생기지 않도록 도와준답니다. (무슨 의미인지는 모르겠..)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UI 개발에 있어서 종종 제목이 강조되지 않아야 할 때가 있는데, 이를 위해 일단 제거한다고 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;리스트 태그에 스타일이 없습니다.&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;ol, ul { list-style: none; margin: 0; padding: 0; }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;이미지는 block입니다.&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;img, svg, video, canvas, audio, iframe, embed, object { display: block; vertical-align: middle; }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;display: inline으로 지정되어 있음으로서 발생하는 다양한 문제들을 사전에 차단합니다.&lt;/p&gt;
&lt;h3&gt;테두리 스타일들을 전역적으로 재설정합니다.&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;\*, \*::before, \*::after { border-width: 0; border-style: solid; border-color: theme(&amp;#39;borderColor.default&amp;#39;, currentColor); }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;테두리 커스터마이징을 쉽게 하기 위함입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;이보다 더 많은 스타일들이 있지만, 가장 중요한 몇 개만 설명하였습니다. 자세한 내용은 &lt;a href=&quot;https://unpkg.com/tailwindcss@1.4.6/dist/base.css&quot;&gt;여기&lt;/a&gt;를 클릭하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;커스터마이징&lt;/h2&gt;
&lt;h3&gt;Pre-flight Extension&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;@tailwind base;
h1 { @apply text-2xl; }
h2 { @apply text-xl; }
h3 { @apply text-lg; }
a { @apply text-blue-600 underline; }
@tailwind components;
@tailwind utilities;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위와 같이 @tailwind base 아래에 기본 스타일에 대한 커스터마이징을 할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;tailwind.config.js&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;module.exports = { purge: \[\], theme: { extend: {}, }, variants: {}, plugins: \[\], }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이는 아직 사용해보지 못하였으므로 추후에 기재하겠습니다. 이 &lt;a href=&quot;https://tailwindcss.com/docs/functions-and-directives/#theme&quot;&gt;링크&lt;/a&gt;를 클릭하여 자세히 알아볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;루트 폴더에 생성된 &lt;code&gt;tailwind.config.js&lt;/code&gt;에서 다양한 기능들을 사용하고 설정할 수 있다.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://tailwindcss.com/docs/&quot;&gt;https://tailwindcss.com/docs/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://dev.to/maurogarcia_19/setup-your-angular-project-to-work-with-tailwindcss-1p5f&quot;&gt;https://dev.to/maurogarcia_19/setup-your-angular-project-to-work-with-tailwindcss-1p5f&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>공부/Angular</category>
      <category>Angular</category>
      <category>tailwindcss</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/111</guid>
      <comments>https://hoondev.tistory.com/111#entry111comment</comments>
      <pubDate>Tue, 14 Jul 2020 17:09:32 +0900</pubDate>
    </item>
    <item>
      <title>Angular 의존성 주입 - (4) 선택적 의존성 주입</title>
      <link>https://hoondev.tistory.com/110</link>
      <description>&lt;h2&gt;선택적 의존성 주입&lt;/h2&gt;
&lt;p&gt;@Optional 데코레이터를 사용하여 의존성 주입이 필수가 아님을 Angular에 명시한다. 이를 사용하면 의존성이 없더라고 앱이 중단되지 않는다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-tsx&quot;&gt;export class TheComponent {
    constructor(**@Optional** private apiUrl: TheService) {
        ...
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부/Angular</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/110</guid>
      <comments>https://hoondev.tistory.com/110#entry110comment</comments>
      <pubDate>Tue, 7 Jul 2020 14:38:08 +0900</pubDate>
    </item>
    <item>
      <title>Angular 서비스 주입 - (3) 인젝션 토큰</title>
      <link>https://hoondev.tistory.com/109</link>
      <description>&lt;h2&gt;인젝션 토큰&lt;/h2&gt;
&lt;p&gt;앞서 알아본 값 프로바이더에서 문자열이나 숫자 등을 토큰으로 문자열을 사용하거나, 클래스를 사용하여야 했다. 값 프로바이더에서 문자열을 토큰으로 사용할 경우 &lt;strong&gt;중복될 위험&lt;/strong&gt;이 있고, 클래스를 토큰으로 사용할 경우 로직이 이상해졌다.&lt;/p&gt;
&lt;p&gt;인젝션 토큰은 &lt;strong&gt;클래스가 아닌 객체, 문자열, 함수 등을 위한 토큰을 주입받기 위해&lt;/strong&gt; 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;export const GET_API_URL: string = &amp;#39;https://api.myapp.com/api/get&amp;#39;;

export const API_URL = new InjectionToken&amp;lt;string&amp;gt;(&amp;#39;api-url&amp;#39;);

export const ApiUrlProvider = {
    provider: API_URL,
    useValue: GET_API_URL
};

~

@Component({
    ~
    providers: [ApiUrlProvider]
})
export class TheComponent {
    constructor(@Inject(API_URL) private apiUrl: string) {
        ...
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부/Angular</category>
      <category>Angular</category>
      <category>service</category>
      <category>서비스</category>
      <category>인젝션토큰</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/109</guid>
      <comments>https://hoondev.tistory.com/109#entry109comment</comments>
      <pubDate>Tue, 7 Jul 2020 14:37:32 +0900</pubDate>
    </item>
    <item>
      <title>Angular 의존성 주입 - (2) 프로바이더 (Provider)</title>
      <link>https://hoondev.tistory.com/108</link>
      <description>&lt;h2&gt;프로바이더 (Provider)&lt;/h2&gt;
&lt;p&gt;Angular는 서비스의 인스턴스 생성과 구성요소에 그 서비스를 주입하는 권한을 위임 받았다. 그러나, Angular는 인스턴스를 어떻게 생성하는지 모르므로 이를 알려줘야 한다. 그 역할을 프로바이더가 한다.&lt;/p&gt;
&lt;p&gt;따라서 프로바이더는 Angular에 의존성 인스턴스의 &lt;strong&gt;생성 정보&lt;/strong&gt;를 알린다.&lt;/p&gt;
&lt;h3&gt;프로바이더 사용 방법&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;@Injectable의 provideIn 프로퍼티&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;// 루트 인젝터에 제공
@Injectable({
    providedIn: &amp;#39;root&amp;#39;,
})

// 특정 모듈에 등록
// 그 모듈의 **모든 구성요소에서 주입할 수 있음.**
@Injectable({
    providedIn: YourModule,
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;@Component 메타데이터의 providers 프로퍼티&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;    // 해당 컴포넌트와 하위 컴포넌트에 주입할 수 있음.
@Component({
    ...
    providers: [TempService]
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;@NgModule 메타데이터의 providers 프로퍼티&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;// 그 모듈의 **모든 구성요소에서 주입할 수 있음.**
@NgModule({
    ...
    providers: [TempService]
})&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;프로바이더의 종류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클래스 프로바이더 : 앞에서 설명했으므로 생략&lt;/li&gt;
&lt;li&gt;값 프로바이더&lt;/li&gt;
&lt;li&gt;팩토리 프로바이더&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;값 프로바이더&lt;/h3&gt;
&lt;p&gt;주입 대상의 타입이 클래스가 아닌 문자열, 숫자, 불리언 타입일 경우&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;providers: [
    {
        provide: &amp;#39;API&amp;#39;,
        useValue: &amp;#39;https://api.myserver.com/get&amp;#39;
        // provide 토큰을 클래스로 지정할 수 없으므로 문자열로 한다.
    }
]

~

constructor(
    // 문자열은 타입 추론이 안되므로 @Inject 데코레이터를 사용한다.
    @Inject(&amp;#39;API&amp;#39;) private api: string
)&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;팩토리 프로바이더&lt;/h3&gt;
&lt;p&gt;의존성 인스턴스를 생성할 때 어떠한 로직을 거쳐야 할 때, 팩토리 함수를 통해 로직을 처리하고 인스턴스를 생성한다.&lt;/p&gt;
&lt;p&gt;~~.service.provider.ts를 만들어서 팩토리 프로바이더와 팩토리 함수를 정의한다. 아래 예시를 보자.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { TestService } from &amp;#39;./test-service-1&amp;#39;;
import { MockTestService } from &amp;#39;./test-service-2&amp;#39;;

// Factory Function
const factoryFunc = (param) =&amp;gt; param ? new TestService : new MockTestService;

// Factory Provider
export const TestServiceProvider = {
    provide: TestService, 
    use**Factory**: factoryFunc, // 팩토리 함수 등록
    deps: [&amp;#39;param&amp;#39;]
};

// Provider that injects value to factory function
export const SetParamProvider = {
    provide: &amp;#39;param&amp;#39;,
    useValue: false
}

~

// Component
@Component({
    ...
    providers: [
        TestServiceProvider,
        SetParamProvider
    ]
})&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;provide : 최종적으로 생성될 인스턴스 Type&lt;/li&gt;
&lt;li&gt;useFactory : 사용할 팩토리 함수&lt;/li&gt;
&lt;li&gt;deps : 팩토리 함수에 주입할 의존성 토큰 배열&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>공부/Angular</category>
      <category>Angular</category>
      <category>provider</category>
      <category>service</category>
      <category>서비스</category>
      <category>프로바이더</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/108</guid>
      <comments>https://hoondev.tistory.com/108#entry108comment</comments>
      <pubDate>Tue, 7 Jul 2020 11:37:59 +0900</pubDate>
    </item>
    <item>
      <title>Angular 의존성 주입 - (1) 서비스</title>
      <link>https://hoondev.tistory.com/107</link>
      <description>&lt;h2&gt;서비스 (Service)&lt;/h2&gt;
&lt;h3&gt;사용하는 이유&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컴포넌트의 독립성을 보장하여 재사용성을 높이기 위해&lt;/li&gt;
&lt;li&gt;프로젝트의 복잡성을 낮추기 위해&lt;/li&gt;
&lt;li&gt;특정 기능을 어플리케이션 전역으로 분리하여 사용하기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;코드&lt;/h3&gt;
&lt;p&gt;서비스를 처음 생성하면 아래와 같은 기본 코드가 생성된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { Injectable } from &amp;#39;@angular/core&amp;#39;;

@Injectable({
  providedIn: &amp;#39;root&amp;#39;,
})
export class TempService {
  constructor() { }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;@Injectable 데코레이터&lt;/h3&gt;
&lt;p&gt;서비스를 정의하는 클래스 위에 &lt;code&gt;@Injectable&lt;/code&gt;이라는 데코레이터가 있다. 이 데코레이터는 Angular가 서비스를 정의하는 이 클래스를 서비스로서 인식하고 Dependency로 주입할 수 있도록 &lt;strong&gt;인젝터&lt;/strong&gt;에 &lt;strong&gt;프로바이더&lt;/strong&gt;로 등록한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;provideIn&lt;/code&gt; : Angular 6에서 도입된 것으로, 프로퍼티 값으로 &lt;code&gt;root&lt;/code&gt;를 설정하면 &lt;strong&gt;루트 인젝터&lt;/strong&gt;에게 서비스를 제공하도록 지시한다. 이 경우, &lt;strong&gt;싱글톤&lt;/strong&gt;으로 생성되어 앱 전역에서 서비스를 Injection할 수 있게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;서비스를 컴포넌트에서 사용하기&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;// 의존성 주입 패턴
constructor(private tempService: TempService) {} // Angular에게 인스턴스 주입 위임
// 위와 같이 생성자 파라미터에 접근 제한자를 선언하면 프로퍼티로 생성된다.

// 사용하지 말아야 할 패턴
tempService: TempService; // Property 생성
constructor() {
    this.tempService = new TempService(); // 직접 인스턴스 생성하고 할당
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;두 번째 코드와 같이 컴포넌트에서 서비스의 인스턴스를 생성하면, 서비스와 컴포넌트는 &lt;strong&gt;긴밀한 결합&lt;/strong&gt;을 하게 된다. 이 경우 컴포넌트와 서비스가 서로 크게 의존하게 되어, 하나의 객체를 변경하면 다른 하나의 객체 또한 변경하여야 한다. 이는 큰 프로젝트일 수록 변경점을 확인하고 수정점에 대해 대응하기가 어렵다.&lt;/p&gt;
&lt;p&gt;이를 해결하기 위해 인스턴스 생성을 Angular에서 하고, 그 인스턴스를 Angular가 컴포넌트에 주입해주는 첫 번째 코드 즉, &lt;code&gt;인스턴스 주입 방식&lt;/code&gt;을 이용한다. → &lt;strong&gt;느슨한 결합&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;앞서 설명했던 &lt;code&gt;provideIn: &amp;#39;root&amp;#39;&lt;/code&gt; 가 느슨한 결합을 구현하기 위해 Angular에게 인스턴스 생성 주체를 위임하는 것이다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;서비스는 항상 컴포넌트에서만 사용할 수 있는 것은 아니므로, 앞으로는 &lt;strong&gt;구성요소&lt;/strong&gt;라고 칭합니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>공부/Angular</category>
      <category>Angular</category>
      <category>service</category>
      <category>서비스</category>
      <category>의존성</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/107</guid>
      <comments>https://hoondev.tistory.com/107#entry107comment</comments>
      <pubDate>Tue, 7 Jul 2020 11:37:14 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript에서의 this와 this 바인딩</title>
      <link>https://hoondev.tistory.com/106</link>
      <description>&lt;h2&gt;흔한 객체지향 언어에서의 this&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;는 Java와 같은 객체지향 언어에서 주로 &lt;strong&gt;이 인스턴스(즉, 자신)&lt;/strong&gt;를 가리키기 위해 사용한다. 아래 코드와 같이.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Person {
  private String name;

  Person(String name) {
      this.name = name;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 예제는 Java에서의 &lt;code&gt;this&lt;/code&gt;의 용례를 보여주기 위한 코드이다. Java에서 &lt;code&gt;this&lt;/code&gt;는 주로 매개변수와 인스턴스 자신의 프로퍼티(멤버) 변수의 이름이 같을 경우 이를 구분하기 위해 사용한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;JavaScript에서의 this&lt;/h2&gt;
&lt;p&gt;그러나, JavaScript에서의 &lt;code&gt;this&lt;/code&gt;는 &lt;strong&gt;함수 호출을 어떻게 하느냐(선언이 아님!!)&lt;/strong&gt;에 따라 다른 객체들이 바인딩된다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;는 &lt;strong&gt;기본적&lt;/strong&gt;으로 &lt;strong&gt;전역객체&lt;/strong&gt;를 참조한다.&lt;br&gt;전역 함수는 물론이거나와, 그 함수의 내부에 있는 함수까지도 &lt;code&gt;this&lt;/code&gt;는 전역객체를 참조한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;를 생성자 함수에서, 혹은 객체의 메소드에서 사용하는 경우가 아니면, &lt;code&gt;this&lt;/code&gt;는 &lt;strong&gt;전역객체&lt;/strong&gt;를 참조한다. 브라우저에서는 &lt;code&gt;window&lt;/code&gt;를 참조하게 된다.&lt;/p&gt;
&lt;h3&gt;그냥 함수를 호출했을 때의 this&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function Person(name) {
  this.name = name; // this === window
}

const me = Person(&amp;#39;hoondev&amp;#39;);

console.log(me); // undefined
console.log(name); // hoondev
console.log(this); // window 객체
console.log(this.name); // hoondev&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이번에는 생성자 함수로서가 아니라, 그냥 함수의 호출로서 사용하였다. 그러므로 &lt;code&gt;this&lt;/code&gt;는 자연스레 &lt;strong&gt;전역객체를 참조&lt;/strong&gt;하게 되었다. 따라서, &lt;code&gt;name&lt;/code&gt;은 &lt;strong&gt;전역변수&lt;/strong&gt;로서 선언이 된 것이다. Person 함수의 리턴값이 없으므로 &lt;code&gt;undefined&lt;/code&gt;이다.&lt;/p&gt;
&lt;h3&gt;일반 함수의 내부 함수에서의 this&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function func() {
  console.log(this); // window 객체
  function nestedFunc() {
    console.log(this); // window 객체
  }
  nestedFunc();
}
func();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;내부 함수에서도 &lt;code&gt;this&lt;/code&gt;는 외부 함수가 아닌 전역 객체를 참조한다.&lt;/p&gt;
&lt;h3&gt;메소드의 내부 함수에서의 this&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const obj = {
  text: &amp;#39;hoondev&amp;#39;,
  func: function() {
    console.log(this); // obj 객체
    console.log(this.text); // hoondev
    function nestedFunc() {
      console.log(this); // window
      console.log(this.text); // undefined
    }
    nestedFunc();
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;객체의 함수, 즉 메소드를 호출하는 경우, 그 메소드의 &lt;code&gt;this&lt;/code&gt;는 &lt;strong&gt;해당 메소드를 프로퍼티로 가지는 객체&lt;/strong&gt;를 참조한다.&lt;br&gt;그래서, func에서의 this는 obj를 가리킨다.&lt;/p&gt;
&lt;p&gt;그러나, 메소드의 내부 함수에서의 this는 전역 객체를 참조한다.&lt;/p&gt;
&lt;h3&gt;생성자 함수를 호출했을 때 this&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function Person(name) {
  this.name = name; // this === window
}

const me = new Person(&amp;#39;hoondev&amp;#39;);
console.log(me.name); // hoondev
console.log(name); // ReferenceError: name is not defined

const me2 = Person(&amp;#39;hoondev&amp;#39;);
console.log(me2.name); // ReferenceError: name is not defined
console.log(name); // hoondev&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;함수를 생성자로서 사용하는 경우, &lt;code&gt;this&lt;/code&gt;는 여느 객체지향 언어와 같이 &lt;strong&gt;자기 자신&lt;/strong&gt;을 참조한다.&lt;/p&gt;
&lt;h3&gt;콜백함수에서의 this&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let a = 1;
const obj = {
  let a = 1;
  func: function() {
    setTimeout(function() {
      console.log(this); // window
      console.log(this.a); // 1
    }, 100);
  }
}

obj.func();&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;this 바인딩&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;는 함수 호출 패턴에 따라 결정된다고 하였다. 그러나 이를 무시하고, &lt;code&gt;this&lt;/code&gt;가 무엇을 가리키는지 &lt;strong&gt;명시적 바인딩&lt;/strong&gt;을 해줄 수 있다. 그러나 이 바인딩 방식은 Arrow Function에서는 적용할 수 없다.&lt;/p&gt;
&lt;h3&gt;apply&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;에 특정 객체를 바인딩하고, 바인딩한 그 함수를 호출한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const School = function (name, pos) {
  this.name = name;
  this.pos = pos;
}

const obj = {};

School.apply(obj, [&amp;#39;Namsan Mid-School&amp;#39;, &amp;#39;Busan&amp;#39;]);
console.log(obj); // { name: &amp;#39;Namsan Mid-School&amp;#39;, pos: &amp;#39;Busan&amp;#39; }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;call&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;apply&lt;/code&gt;와 동일하지만, 두 번째 인자로 넘겨주는 arguments를 배열의 형태가 아니라 각각 전달해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const School = function (name, pos) {
  this.name = name;
  this.pos = pos;
}

const obj = {};

School.call(obj, &amp;#39;Namsan Mid-School&amp;#39;, &amp;#39;Busan&amp;#39;);
console.log(obj); // { name: &amp;#39;Namsan Mid-School&amp;#39;, pos: &amp;#39;Busan&amp;#39; }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;bind&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;bind&lt;/code&gt;에 인자로 전달한 객체가 &lt;code&gt;this&lt;/code&gt;에 바인딩되고, 바인딩된 그 함수를 리턴한다. 리액트의 Class Component에서 많이 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const obj = {};
const Home = function() {
  ...
}.bind(obj);&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부/JavaScript</category>
      <category>apply</category>
      <category>bind</category>
      <category>call</category>
      <category>javascript</category>
      <category>this</category>
      <category>this바인딩</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/106</guid>
      <comments>https://hoondev.tistory.com/106#entry106comment</comments>
      <pubDate>Sat, 27 Jun 2020 02:14:23 +0900</pubDate>
    </item>
    <item>
      <title>브라우저의 렌더링 원리</title>
      <link>https://hoondev.tistory.com/105</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;이 문서에서 사용되는 그림은 모두 네이버 D2의 &lt;a href=&quot;https://d2.naver.com/helloworld/59361&quot;&gt;브라우저는 어떻게 동작하는가?&lt;/a&gt;에서 발췌하였습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;브라우저의 구성 요소&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zDCDT/btqFaho8s8b/7xxNvlrxOHdKRLcxseERek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zDCDT/btqFaho8s8b/7xxNvlrxOHdKRLcxseERek/img.png&quot; data-alt=&quot;출처 : 네이버 D2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zDCDT/btqFaho8s8b/7xxNvlrxOHdKRLcxseERek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzDCDT%2FbtqFaho8s8b%2F7xxNvlrxOHdKRLcxseERek%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 네이버 D2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;사용자 인터페이스&lt;/code&gt; - 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;브라우저 엔진&lt;/code&gt; - 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;렌더링 엔진&lt;/code&gt; - 요청한 콘텐츠를 표시. 예를 들어 HTML을 요청하면 &lt;strong&gt;HTML과 CSS를 파싱&lt;/strong&gt;하여 화면에 표시함.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;통신&lt;/code&gt; - &lt;strong&gt;HTTP 요청과 같은 네트워크 호출&lt;/strong&gt;에 사용됨. 이것은 &lt;strong&gt;플랫폼 독립적인 인터페이스&lt;/strong&gt;이고 각 플랫폼 하부에서 실행됨.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UI 백엔드&lt;/code&gt; - 콤보 박스와 창 같은 기본적인 장치를 그림. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;자바스크립트 해석기&lt;/code&gt; - 자바스크립트 코드를 해석하고 실행.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;자료 저장소&lt;/code&gt; - 이 부분은 자료를 저장하는 계층이다. 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다. HTML5 명세에는 브라우저가 지원하는 &amp;#39;웹 데이터 베이스&amp;#39;가 정의되어 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지한다. 즉, 각 탭은 독립된 프로세스로 처리된다.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;(그래서 메모리를 많이 먹나보다...)&lt;/del&gt;&lt;/p&gt;
&lt;h3&gt;렌더링 엔진이란?&lt;/h3&gt;
&lt;p&gt;렌더링 엔진은 서버로부터 요청 받은 내용을 브라우저의 화면에 표시하는 일을 한다.&lt;/p&gt;
&lt;p&gt;렌더링 엔진은 HTML, XML 문서, 이미지를 표시할 수 있다. 플러그인, 브라우저 확장 기능 등을 이용해 PDF와 같은 다른 리소스도 표현할 수 있다.&lt;/p&gt;
&lt;h3&gt;렌더링 엔진의 종류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Chrome의 V8&lt;/li&gt;
&lt;li&gt;Safari의 WebKit&lt;/li&gt;
&lt;li&gt;Firefox의 Gecko&lt;del&gt;(개코..?)&lt;/del&gt;&lt;br&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;렌더링 엔진의 동작 과정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;helloworld-59361-2.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOmCi0/btqFbBsXG6h/IjLkLHratK8GQZXnAybNxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOmCi0/btqFbBsXG6h/IjLkLHratK8GQZXnAybNxK/img.png&quot; data-alt=&quot;출처 : 네이버 D2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOmCi0/btqFbBsXG6h/IjLkLHratK8GQZXnAybNxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOmCi0%2FbtqFbBsXG6h%2FIjLkLHratK8GQZXnAybNxK%2Fimg.png&quot; data-filename=&quot;helloworld-59361-2.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 네이버 D2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HTML 문서를 파싱하고 변환하여 &lt;code&gt;DOM(Document Object Model) 트리&lt;/code&gt;를 생성한다.&lt;/li&gt;
&lt;li&gt;외부 CSS 파일과 함께 인라인 스타일 요소를 파싱하고 변환하여 &lt;code&gt;CSSOM(CSS Object Model) 트리&lt;/code&gt;를 생성한다.&lt;/li&gt;
&lt;li&gt;DOM 트리와 CSSOM 트리를 이용하여 &lt;code&gt;렌더 트리&lt;/code&gt;를 생성한다.&lt;/li&gt;
&lt;li&gt;렌더 트리의 생성이 종료되면, 렌더 트리의 각 노드들을 정확한 위치에 &lt;strong&gt;배치&lt;/strong&gt;하고 다양한 &lt;strong&gt;값을 계산&lt;/strong&gt;한다.&lt;/li&gt;
&lt;li&gt;브라우저의 실제 화면에 &lt;strong&gt;그리기&lt;/strong&gt; 과정을 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;helloworld-59361-3.png&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;289&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uDNO8/btqFaN8WMA0/BWX6nkJrWpqGFee4TWzyN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uDNO8/btqFaN8WMA0/BWX6nkJrWpqGFee4TWzyN0/img.png&quot; data-alt=&quot;출처 : 네이버 D2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uDNO8/btqFaN8WMA0/BWX6nkJrWpqGFee4TWzyN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuDNO8%2FbtqFaN8WMA0%2FBWX6nkJrWpqGFee4TWzyN0%2Fimg.png&quot; data-filename=&quot;helloworld-59361-3.png&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;289&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 네이버 D2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 그림은, Safari의 WebKit 엔진의 동작 과정을 나타낸 것이다.&lt;/p&gt;</description>
      <category>공부/WEB</category>
      <category>CSSOM</category>
      <category>Dom</category>
      <category>렌더링</category>
      <category>브라우저</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/105</guid>
      <comments>https://hoondev.tistory.com/105#entry105comment</comments>
      <pubDate>Fri, 26 Jun 2020 22:39:43 +0900</pubDate>
    </item>
    <item>
      <title>HTML5에서의 Sementic Tag(시맨틱 태그)</title>
      <link>https://hoondev.tistory.com/104</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot; width=&quot;384&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OtKnD/btqFaTA8GYZ/G4ssKGVMILW6bVpjH5fDIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OtKnD/btqFaTA8GYZ/G4ssKGVMILW6bVpjH5fDIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OtKnD/btqFaTA8GYZ/G4ssKGVMILW6bVpjH5fDIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOtKnD%2FbtqFaTA8GYZ%2FG4ssKGVMILW6bVpjH5fDIk%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot; width=&quot;384&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;Sementic Tag란?&lt;/h2&gt;
&lt;p&gt;글자 그대로 해석하면, &amp;quot;의미론적인&amp;quot; 태그라는 뜻이다.&lt;br&gt;즉, 보다 더 명시적으로 의미를 알아볼 수 있는 태그를 쓸 수 있다는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;라는 이름의 태그는 딱 봐도 앱의 헤더 부분을 나타내는 태그라는 것을 알 수 있고, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;는 딱 봐도 앱의 아래 부분을 나타내는 태그라는 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;반면에 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;나 &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 태그는 내부의 요소가 어떤 의미를 가지는지 알 수 없다. 따라서, &lt;strong&gt;non-sementic&lt;/strong&gt; 태그인 것이다.&lt;/p&gt;
&lt;p&gt;또한, 시맨틱 태그는 SEO 최적화가 된다. 검색 엔진이 정보를 검색할 때, 시맨틱 태그에서 중요한 정보를 뽑아 탐색에 반영한다. 이처럼 시맨틱 태그를 통해 웹 문서가 구조화되어 의미 있는 내용을 탐색할 수 있도록 하는 웹을 &lt;strong&gt;시맨틱 웹&lt;/strong&gt;이라고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEydHl/btqE9K58tvI/4MYovp36IAnfqSk7pjViKk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEydHl/btqE9K58tvI/4MYovp36IAnfqSk7pjViKk/img.gif&quot; data-alt=&quot;출처 : w3schools&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEydHl/btqE9K58tvI/4MYovp36IAnfqSk7pjViKk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bEydHl/btqE9K58tvI/4MYovp36IAnfqSk7pjViKk/img.gif&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : w3schools&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;Sementic Tag 종류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3schools.com/html/html5_semantic_elements.asp&quot;&gt;자세히 알아보기&lt;/a&gt;&lt;/p&gt;</description>
      <category>공부/WEB</category>
      <category>html5</category>
      <category>semantic</category>
      <category>시맨틱태그</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/104</guid>
      <comments>https://hoondev.tistory.com/104#entry104comment</comments>
      <pubDate>Fri, 26 Jun 2020 22:17:16 +0900</pubDate>
    </item>
    <item>
      <title>ES6에서 Arrow Function 사용하기</title>
      <link>https://hoondev.tistory.com/103</link>
      <description>&lt;h3&gt;관련 포스트&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/100&quot;&gt;JavaScript ECMAScript란?&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Arrow Function의 특징&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;function 표현에 비해 구문이 짧다.&lt;/li&gt;
&lt;li&gt;자신의 this, arguments를 바인딩하지 않는다.&lt;/li&gt;
&lt;li&gt;항상 익명 함수로만 사용된다.&lt;/li&gt;
&lt;li&gt;생성자로서 사용할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Arrow Function 사용하기&lt;/h2&gt;
&lt;h3&gt;매개변수가 없을 때&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const func = () =&amp;gt; { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;매개변수가 1개일 때&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const func1 = i =&amp;gt; { ... } // 소괄호의 지정 불필요!
const func2 = (i) =&amp;gt; { ... } // 소괄호 지정해도 무관!&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;매개변수가 2개 이상일 때&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const func = (x, y) =&amp;gt; { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;함수 Body&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const func = i =&amp;gt; { 
  return i * i;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;한 줄의 구문만 있는 경우&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const func = i =&amp;gt; i * i; // 중괄호와 return을 생략할 수 있음. i * i 값이 리턴된다.&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Arrow Function 호출하기&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const add = (a, b) =&amp;gt; a + b;
console.log(add(1, 2)); // 3&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Arrow Function 콜백 함수로 전달하기&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const arr = [1, 2, 3, 4, 5];
const isEven = arr.map((i) =&amp;gt; i % 2);
console.log(isEven); // [0, 1, 0, 1, 0]&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;code&gt;중요&lt;/code&gt; Arrow Function에서의 this&lt;/h2&gt;
&lt;h3&gt;일반 함수에서의 this&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/106&quot;&gt;JavaScript에서의 this와 this 바인딩&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Arrow Function에서의 this&lt;/h3&gt;
&lt;p&gt;일반 함수에서의 &lt;code&gt;this&lt;/code&gt;는 함수가 선언될 때가 아닌, &lt;strong&gt;호출&lt;/strong&gt;될 때, 그 &lt;strong&gt;호출 Context&lt;/strong&gt;에 따라 &lt;strong&gt;동적&lt;/strong&gt;으로 바인딩된다. 반면에, Arrow Function은 함수가 &lt;strong&gt;선언&lt;/strong&gt;될 때 &lt;strong&gt;정적&lt;/strong&gt;으로 바인딩된다.&lt;/p&gt;
&lt;p&gt;Arrow Function에서의 this는 항상, &lt;strong&gt;상위 스코프의 &lt;code&gt;this&lt;/code&gt;&lt;/strong&gt;를 가리킨다.&lt;br&gt;이를 &lt;code&gt;Lexical this&lt;/code&gt;라고 부른다. JavaScript의 Lexical scope 개념과 유사하다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const me = {
  arr: [1, 2, 3],
  show() {
    function func() {
      console.log(this.arr); // undefined
    }
    func();
  },
  showArrow() {
    func = () =&amp;gt; {
      console.log(this.arr); // [1, 2, 3]
    };
    func();
  },
};

me.show();
me.showArrow();&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;Arrow Function을 사용해서는 안되는 경우&lt;/h2&gt;
&lt;h3&gt;메소드 정의로 사용하는 경우&lt;/h3&gt;
&lt;p&gt;객체의 함수, 즉 메소드로서 정의해서는 안된다. 일반 함수가 객체의 메소드로 정의되는 경우에는 인스턴스 자기 자신을 가리키지만, Arrow Function은 항상 &lt;strong&gt;상위 스코프의 &lt;code&gt;this&lt;/code&gt;&lt;/strong&gt;를 가리키므로 사용해서는 안된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const me = {
  name: &amp;#39;Hoon&amp;#39;,
  getMyName: () =&amp;gt; this.name; // this는 상위 스코프의 this인 window를 가리키게 됨.
}
console.log(me.getMyname()); // undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이런 경우에는 ES6에서 제공하는 축약 메소드 표현을 사용하자.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const me = {
  name: &amp;#39;Hoon&amp;#39;,
  getMyName() { return this.name; }
}
console.log(me.getMyname()); // Hoon&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;prototype의 메소드&lt;/h3&gt;
&lt;h3&gt;생성자 함수&lt;/h3&gt;
&lt;hr&gt;
&lt;h2&gt;참고문서&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://poiemaweb.com/es6-arrow-function&quot;&gt;PolemaWEB&lt;/a&gt;&lt;/p&gt;</description>
      <category>공부/JavaScript</category>
      <category>arrowfunction</category>
      <category>es6</category>
      <category>javascript</category>
      <category>this</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/103</guid>
      <comments>https://hoondev.tistory.com/103#entry103comment</comments>
      <pubDate>Fri, 26 Jun 2020 04:03:19 +0900</pubDate>
    </item>
    <item>
      <title>ES6에서 let/const로 Block-scoped 변수 선언하기</title>
      <link>https://hoondev.tistory.com/102</link>
      <description>&lt;h3&gt;관련 포스트&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/100&quot;&gt;JavaScript ECMAScript란?&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;변수의 Block-scoped 선언&lt;/h2&gt;
&lt;h3&gt;let&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;let&lt;/code&gt;을 이용해 &lt;code&gt;Block-scoped&lt;/code&gt;인 변수를 선언할 수 있다. &lt;strong&gt;중괄호로 구분된 영역&lt;/strong&gt;을 &lt;code&gt;Block-scoped&lt;/code&gt; 영역이라고 한다. 이는 기존의 &lt;code&gt;var&lt;/code&gt; 키워드의 문제점을 해결할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function funcVar() {
  console.log(k); // undefined
  var k = 1;
  console.log(k); // 1
}
funcVar();

function funcLet() {
  console.log(a); // ReferenceError: Cannot access &amp;#39;a&amp;#39; before initialization (오류 발생)
  let a = 1;
  console.log(a); // 1
}
funcLet();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;var&lt;/code&gt;로 선언된 변수 k는 호이스팅에 의해 변수 선언문 이전에도 접근이 가능하며, undefined라는 값을 가진다.&lt;br&gt;그 이유는 &lt;a href=&quot;https://hoondev.tistory.com/101&quot;&gt;JavaScript에서 var를 사용하면 안되는 이유&lt;/a&gt;에서 설명하였으니 패스!&lt;/p&gt;
&lt;p&gt;반면에 &lt;code&gt;let&lt;/code&gt;은 &lt;code&gt;var&lt;/code&gt;와 같이 스코프에 진입할 때 변수가 만들어지지만, 코드 위치에 도달할 때까지 액세스가 불가능하게 해놓았다. (호이스팅이 안되는 것은 아니다!) 따라서 &lt;code&gt;ReferenceError: Cannot access &amp;#39;a&amp;#39; before initialization&lt;/code&gt;과 같은 오류가 뜨는 것이다.&lt;/p&gt;
&lt;p&gt;이에 관해 깊이 있게 공부하고 싶다면, &lt;a href=&quot;https://medium.com/sjk5766/var-let-const-%ED%8A%B9%EC%A7%95-%EB%B0%8F-scope-335a078cec04&quot;&gt;여기&lt;/a&gt;를 참고하면 된다.&lt;/p&gt;
&lt;h3&gt;const&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt;는 &lt;code&gt;let&lt;/code&gt;과 대부분 동일하나, 선언과 동시에 값이 할당되어야 한다. 또한 &lt;code&gt;const&lt;/code&gt;이라는 글자 그대로 &lt;code&gt;상수&lt;/code&gt;로서 취급되므로 이후 값의 수정이 불가능하다.&lt;/p&gt;</description>
      <category>공부/JavaScript</category>
      <category>const</category>
      <category>es6</category>
      <category>let</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/102</guid>
      <comments>https://hoondev.tistory.com/102#entry102comment</comments>
      <pubDate>Fri, 26 Jun 2020 03:29:08 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript에서 var를 사용하면 안되는 이유</title>
      <link>https://hoondev.tistory.com/101</link>
      <description>&lt;h2&gt;var&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;var&lt;/code&gt;는 ES6 등장 이전에 사용되던 키워드이며, 변수를 생성할 때 앞에 붙여서 변수임을 명시합니다.&lt;br&gt;그러나 이는 &lt;strong&gt;개발에 있어서 엄청 큰 단점&lt;/strong&gt;을 가지고 있어 현재에는 거의 사용하지 않습니다. (사용하면 안됩니다..)&lt;/p&gt;
&lt;p&gt;먼저 아래 코드를 봅시다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;var a = 123;
console.log(a); // 123

var a = 567;
console.log(a); // 567&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;a가 2번 선언되었음에도 불구하고, 오류는 발생하지 않았습니다.&lt;/p&gt;
&lt;p&gt;만약 방대한 프로젝트를 개발한다면 똑같은 이름의 변수를 몇 번이나 사용해도 오류는 발생하지 않으니, &lt;strong&gt;로직 상의 오류&lt;/strong&gt;는 빈번해질 것이고 그 오류를 &lt;strong&gt;발견하기는 또 굉장히 어렵게 될 것&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;그런데, 왜 이런 현상이 나타나는 것일까요?&lt;br&gt;그 이유는 바로 &lt;code&gt;Hosting(호이스팅)&lt;/code&gt; 때문입니다.&lt;/p&gt;
&lt;h2&gt;호이스팅?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;var&lt;/code&gt; 키워드를 사용하여 변수 선언 시, &lt;strong&gt;해당 변수의 선언부를 스코프 최상단으로 올려버리는 것&lt;/strong&gt;을 말합니다.&lt;br&gt;JavaScript의 &lt;strong&gt;변수 생성과 초기화의 작업이 분리되어 진행되기 때문에&lt;/strong&gt; 이런 현상이 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;var&lt;/code&gt;는 우리가 기존 C나 Java의 Block-scoped가 아니라 &lt;strong&gt;Function-scoped&lt;/strong&gt;입니다. 따라서, 코드 전체의 최상단이 아닌 &lt;strong&gt;함수 내부의 최상단&lt;/strong&gt;으로 이동합니다. 아래 예시를 봅시다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Function-scoped는 중괄호로 구분된 영역의 범위를 갖는 것이 아니라, 함수 내부의 영역을 범위로 갖는 것을 의미합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;var a = 123;
function func() {
  console.log(a); // undefined
  var a = 456;
  console.log(a); // 456
}
func();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드는 var의 호이스팅에 의해 아래와 같이 인식됩니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;var a = 123;
function func() {
  var a;
  console.log(a); // undefined
  a = 456;
  console.log(a); // 456
}
func();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;호이스팅 떄문에 a를 참조할 Reference는 있으니 Reference Error는 나지 않고, 대신 &lt;code&gt;undefined&lt;/code&gt;라는 값이 출력됩니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;참고로 undefined는 JavaScript의 Primitive Value로 어떠한 값도 할당되지 않아 자료형이 정해지지 않은 상태를 의미합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;그래서 var의 문제점은..?&lt;/h2&gt;
&lt;h3&gt;변수의 중복 선언이 가능하다.&lt;/h3&gt;
&lt;p&gt;글의 최상단에서 설명한 예시를 통해 알 수 있듯이, var는 a라는 이름의 변수가 있음에도 불구하고 또 그 아래에서 a라는 이름의 변수를 선언할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이처럼 이미 선언했던 변수명을 모르고 또 사용할 경우, &lt;strong&gt;기존에 있던 변수는 전혀 다른 값&lt;/strong&gt;을 가지게 됩니다. 그 경우, 그 변수를 사용하는 다양한 &lt;strong&gt;로직들에 치명적인 문제&lt;/strong&gt;가 생깁니다.&lt;/p&gt;
&lt;h3&gt;for문에서의 문제점&lt;/h3&gt;
&lt;p&gt;ar는 Function-scoped이기 때문에 for문에서 for문의 순회를 위해 i라는 변수를 var로 선언한 경우, 이 변수는 &lt;strong&gt;for문이 종료되어도 접근이 가능&lt;/strong&gt;하게 됩니다.&lt;/p&gt;
&lt;p&gt;또한, 만약 for문의 함수 내부가 아닌, 함수 외부에 전역적으로 돌아갈 경우 for문에서 사용한 var 변수들은 &lt;strong&gt;전역 변수&lt;/strong&gt;로서 역할을 하므로, &lt;strong&gt;전역 변수가 남발&lt;/strong&gt;될 수 있습니다.&lt;/p&gt;</description>
      <category>공부/JavaScript</category>
      <category>hosting</category>
      <category>javascript</category>
      <category>Var</category>
      <category>호이스팅</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/101</guid>
      <comments>https://hoondev.tistory.com/101#entry101comment</comments>
      <pubDate>Fri, 26 Jun 2020 02:59:52 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript ECMAScript란?</title>
      <link>https://hoondev.tistory.com/100</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;다운로드.jpeg&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;268&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eD7VP8/btqE7PMZGxC/7rz4QTk97RTDr9CP3CYXOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eD7VP8/btqE7PMZGxC/7rz4QTk97RTDr9CP3CYXOk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eD7VP8/btqE7PMZGxC/7rz4QTk97RTDr9CP3CYXOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeD7VP8%2FbtqE7PMZGxC%2F7rz4QTk97RTDr9CP3CYXOk%2Fimg.jpg&quot; data-filename=&quot;다운로드.jpeg&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;268&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;ECMAScript란?&lt;/h2&gt;
&lt;p&gt;ECMA International이라는 정보통신 비영리 표준화 기구에서 정의한 &lt;strong&gt;스크립트 언어에 대한 &amp;#39;사양&amp;#39;&lt;/strong&gt;입니다. 스크립트 언어로서 준수해여 하는 규칙, 지침들을 규정합니다.&lt;/p&gt;
&lt;h2&gt;ECMAScript vs JavaScript?&lt;/h2&gt;
&lt;p&gt;JavaScript는 &lt;strong&gt;ECMAScript의 사양을 준수하는 스크립트 언어&lt;/strong&gt;입니다. 즉, JavaScript는 ECMAScript의 사양을 따라 제작된 &amp;#39;언어&amp;#39;이며, 우리는 이 &amp;#39;언어&amp;#39;를 이용해 스크립트 코딩을 할 수 있는 것입니다.&lt;/p&gt;
&lt;h2&gt;ECMAScript 6 === ES6란?&lt;/h2&gt;
&lt;p&gt;ES6은 ECMAScript의 여섯 번째 릴리즈라고 생각하시면 됩니다. 기존의 콜백 지옥과 같은 불편했던 부분들을 상당 부분 개선하여 내놓은 표준으로, 많은 개발자들이 사랑하고 애용합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;449&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csRNuW/btqE83cEFKg/iuCa4C8c0B9xmQJc3txGg1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csRNuW/btqE83cEFKg/iuCa4C8c0B9xmQJc3txGg1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csRNuW/btqE83cEFKg/iuCa4C8c0B9xmQJc3txGg1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsRNuW%2FbtqE83cEFKg%2FiuCa4C8c0B9xmQJc3txGg1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;449&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그러나, 이러한 ECMAScript 표준은 브라우저에 따라 지원되는 범위가 다릅니다. &lt;strong&gt;이는 브라우저마다 JavaScript를 Interpreting하는 엔진이 다르기 때문&lt;/strong&gt;입니다. 따라서 개발자들은 다양한 브라우저에서 웹앱이 정상적으로 실행될 수 있도록 &lt;code&gt;크로스 브라우징&lt;/code&gt;을 구현해야 합니다.&lt;/p&gt;
&lt;h2&gt;Babel&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;1_XmHUL5DeySv_dGmvbPqdDQ.png&quot; data-origin-width=&quot;3276&quot; data-origin-height=&quot;1488&quot; width=&quot;444&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bThRk3/btqE81lApOL/fDlsA2P4z3caY9EMeNcGW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bThRk3/btqE81lApOL/fDlsA2P4z3caY9EMeNcGW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bThRk3/btqE81lApOL/fDlsA2P4z3caY9EMeNcGW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbThRk3%2FbtqE81lApOL%2FfDlsA2P4z3caY9EMeNcGW1%2Fimg.png&quot; data-filename=&quot;1_XmHUL5DeySv_dGmvbPqdDQ.png&quot; data-origin-width=&quot;3276&quot; data-origin-height=&quot;1488&quot; width=&quot;444&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;개발자들은 ES6에서 도입된 다양한 기능들과 Syntax들을 사용하여 개발의 편의성을 얻을 수 있었지만, 브라우저 간의 호환성 문제를 해결하는 대에는 고역을 겪었습니다. 특히 국내에서 심지어 최근까지도 사용되고 있는 Internet Explorer가 ES6를 대부분 지원하지 않으므로, 한국에서 웹앱을 서비스하기 위해서는 &lt;code&gt;크로스 브라우징&lt;/code&gt;의 구현은 필수였습니다.&lt;/p&gt;
&lt;p&gt;이러한 비생산적이고 귀찮은 과정을 단 한 번에 해결해주는 놈이 등장하였습니다. 바로, 유명한 Transpiler, &lt;code&gt;바벨(Babel)&lt;/code&gt;입니다. 바벨은 &lt;strong&gt;ES6으로 작성된 코드를 &lt;code&gt;크로스 브라우징&lt;/code&gt;을 할 수 있도록 ES5의 코드로 바꿔줍니다.&lt;/strong&gt; 이 &lt;code&gt;Babel&lt;/code&gt;의 등장으로, JavaScript 코딩에서는 크로스 브라우징을 고려하지 않게 되었습니다.&lt;/p&gt;
&lt;h2&gt;그렇다면..&lt;/h2&gt;
&lt;p&gt;그렇다면 JavaScript 개발자라면, 최신 기술과 Syntax가 적용된 ES6를 써보고 싶다는 생각.. 드시지 않나요? 지금 바로 ES6에 추가된 새로운 기능들과 Syntax를 확인해보세요. 다양한 글들이 있습니다!&lt;/p&gt;</description>
      <category>공부/JavaScript</category>
      <category>Babel</category>
      <category>ECMAScript</category>
      <category>es6</category>
      <category>javascript</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/100</guid>
      <comments>https://hoondev.tistory.com/100#entry100comment</comments>
      <pubDate>Fri, 26 Jun 2020 01:12:07 +0900</pubDate>
    </item>
    <item>
      <title>Java Type-casting (타입 캐스팅)</title>
      <link>https://hoondev.tistory.com/99</link>
      <description>&lt;h2&gt;Implicit Casting (암시적 캐스팅)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;정보의 손실, 오류의 가능성이 없는 경우에 허용&lt;/li&gt;
&lt;li&gt;(ex: double d = 3;) : int -&amp;gt; double&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Explicit Casting (명시적 캐스팅)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;오류의 가능성이 있다.&lt;/li&gt;
&lt;li&gt;따라서 프로그래머의 판단에 오류의 가능성이 없고, 타당성이 있을 경우에만 시행함.&lt;/li&gt;
&lt;li&gt;(ex: int i = (int)3.0;) : double -&amp;gt; int, 소수점이 없으므로 손실이 없음.&lt;/li&gt;
&lt;li&gt;(ex: int i = (int)3.3;) : double -&amp;gt; int, 소수점이 손실됨.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>공부/Java</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/99</guid>
      <comments>https://hoondev.tistory.com/99#entry99comment</comments>
      <pubDate>Thu, 25 Jun 2020 17:28:56 +0900</pubDate>
    </item>
    <item>
      <title>Java Literals (리터럴 상수)</title>
      <link>https://hoondev.tistory.com/98</link>
      <description>&lt;h2&gt;Number Literals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Integer Literals, Floating-Point Literals 등을 포괄하는 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Integer Literals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Integer Literal은 Integer Variable(정수 자료형)에 할당될 수 있다.&lt;/li&gt;
&lt;li&gt;Literal 값이 Variable의 최대 할당 크기를 초과하면 컴파일 오류가 발생한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;long&lt;/code&gt; type를 명시적으로 표현하려면 &lt;code&gt;L&lt;/code&gt; 또는 &lt;code&gt;l&lt;/code&gt;을 붙인다. (ex: long longVal = 3141592L;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Floating-Point Literals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기본적으로 Floating-Point Literal은 &lt;code&gt;double&lt;/code&gt; 타입으로 취급된다. (5.0 리터럴은 &lt;code&gt;double&lt;/code&gt;이다.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;float&lt;/code&gt;임을 명시적으로 표현하려면 숫자 뒤에 &lt;code&gt;F&lt;/code&gt; 또는 &lt;code&gt;f&lt;/code&gt;를 붙인다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;double&lt;/code&gt;임을 명시적으로 표현하려면 숫자 뒤에 &lt;code&gt;D&lt;/code&gt; 또는 &lt;code&gt;d&lt;/code&gt;를 붙인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Scientific Notation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Floating-Point Literals는 Scientific Notation으로 표현할 수 있다.&lt;/li&gt;
&lt;li&gt;1.2345e+2, 1.2345e2와 같은 것을 Scientific Notation이라고 한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;E&lt;/code&gt; 혹은 &lt;code&gt;e&lt;/code&gt;를 붙여 지수를 나타내는 표현이다.&lt;/li&gt;
&lt;li&gt;(ex: 1.2345e+2 == 1.2345e2 == 1.2345E2 == 123.45)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>공부/Java</category>
      <category>java</category>
      <category>literals</category>
      <category>리터럴</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/98</guid>
      <comments>https://hoondev.tistory.com/98#entry98comment</comments>
      <pubDate>Thu, 25 Jun 2020 15:46:34 +0900</pubDate>
    </item>
    <item>
      <title>Java Modifiers (접근 제어자)</title>
      <link>https://hoondev.tistory.com/97</link>
      <description>&lt;h2&gt;Modifiers의 종류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;public&lt;/li&gt;
&lt;li&gt;protected&lt;/li&gt;
&lt;li&gt;default&lt;/li&gt;
&lt;li&gt;private&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;접근 허용범위 : &lt;code&gt;public &amp;gt; protected &amp;gt; default &amp;gt; private&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;public&lt;/h2&gt;
&lt;p&gt;public이 붙은 변수, 메소드는 어떤 클래스에서라도 접근이 가능하다.&lt;/p&gt;
&lt;h2&gt;default&lt;/h2&gt;
&lt;p&gt;접근 제어자가 따로 설정되지 않았을 때를 뜻한다. 동일 패키지 내에서만 접근이 가능하다.&lt;/p&gt;
&lt;h2&gt;protected&lt;/h2&gt;
&lt;p&gt;default 처럼 동일 패키지 내에서는 모두 접근이 가능하다. default와 다른 점은 다른 패키지에서도 제한적으로 접근이 가능하다는 것이다.&lt;br&gt;정확히 말하면, &lt;strong&gt;다른 패키지에서 해당 클래스를 상속받는 파생 클래스에서&lt;/strong&gt; 접근이 가능하다.&lt;/p&gt;
&lt;h2&gt;private&lt;/h2&gt;
&lt;p&gt;가장 접근 권한이 적은 접근 제어자이다. &lt;strong&gt;해당 클래스에서만&lt;/strong&gt; 접근이 가능하다.&lt;/p&gt;</description>
      <category>공부/Java</category>
      <category>java</category>
      <category>modifiers</category>
      <category>private</category>
      <category>protected</category>
      <category>public</category>
      <category>접근제어자</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/97</guid>
      <comments>https://hoondev.tistory.com/97#entry97comment</comments>
      <pubDate>Thu, 25 Jun 2020 15:34:03 +0900</pubDate>
    </item>
    <item>
      <title>ES6에서 배열을 활용하는 다양한 방법</title>
      <link>https://hoondev.tistory.com/96</link>
      <description>&lt;h2&gt;기존의 forEach()&lt;/h2&gt;
&lt;p&gt;배열 전체를 돌며 해당 배열의 요소에 어떠한 작업을 수행할 수 있는 메소드이다.&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;arr.forEach((element, index, arr) =&amp;gt; { 작업 });
(return은 undefined)&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3];
let arr2 = [];
arr.forEach((element, index, arr) =&amp;gt; {
  console.log(&amp;#39;현재 값은 &amp;#39; + element + &amp;#39;이며, 인덱스는 &amp;#39; + index + &amp;#39;입니다.&amp;#39;); // A
  arr2.push(element * index); // B
  element *= 2;
  /*
  현재 값은 1이며, 인덱스는 0입니다.
  현재 값은 2이며, 인덱스는 1입니다.
  현재 값은 3이며, 인덱스는 2입니다.
  */
}, []);
console.log(arr); // [ 1, 2, 3 ]
console.log(arr2); // [ 0, 4, 12 ]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;A&lt;/code&gt;와 &lt;code&gt;B&lt;/code&gt;와 같이 배열의 원소들을 이용해 다양한 작업을 할 수 있다.&lt;/p&gt;
&lt;p&gt;눈여겨볼 점은 콜백 내부에서 &lt;code&gt;element *= 2&lt;/code&gt;를 해줬음에도 불구하고, 기존 배열의 값은 변하지 않았음을 알 수 있다. 즉, 기존의 값은 변경시키지 않는 메소드이다. (immutable)&lt;/p&gt;
&lt;p&gt;콜백 내부에서 &lt;code&gt;element, index, arr&lt;/code&gt;를 이용하여 아래에서 소개할 &lt;code&gt;filter()&lt;/code&gt;, &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;find()&lt;/code&gt;, &lt;code&gt;reduce()&lt;/code&gt;와 같은 기능들을 구현할 수 있다. 그러나 매번 이를 구현하기는 매우 귀찮으므로, ES6에서는 아래와 같은 훌륭한 메소드들을 제공한다.&lt;/p&gt;
&lt;h2&gt;filter()&lt;/h2&gt;
&lt;p&gt;기존의 배열에서 조건에 맞는 원소만 뽑아 새로운 배열을 만들어 리턴한다.&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;arr.filter((element, index, arr) =&amp;gt; { return (condition) });&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3, 4, 5, 6];
let arr2 = arr.filter((i) =&amp;gt; i % 2 === 0);
console.log(arr[1] === arr2[0]); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;첫 번째 출력 : &lt;code&gt;arr&lt;/code&gt;에 있는 원소와 &lt;strong&gt;같은 원소&lt;/strong&gt;임을 알 수 있음.&lt;/p&gt;
&lt;h2&gt;find()&lt;/h2&gt;
&lt;p&gt;찾으려는 값을 리턴한다. 여러 개가 있을 경우 처음 값만 리턴한다.&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;arr.find((element, index, arr) =&amp;gt; { return (condition) });&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3, 4, 5, 6];
let value = arr.find((i) =&amp;gt; i % 2 === 0;
console.log(value); // 2
console.log(arr[1] === value); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;첫 번째 출력 : &lt;code&gt;arr&lt;/code&gt;의 여러 2의 배수인 원소들 중 첫 번째 원소만 리턴됨.&lt;br&gt;두 번째 출력 : &lt;code&gt;arr[1](2)&lt;/code&gt;와 &lt;code&gt;value(2)&lt;/code&gt;는 &lt;strong&gt;같은 원소&lt;/strong&gt;임을 알 수 있음.&lt;/p&gt;
&lt;h2&gt;map()&lt;/h2&gt;
&lt;p&gt;반복문을 돌면서 배열의 요소 각각에 대해 인자로 넘겨준 콜백 함수를 적용시킨다(매핑한다).&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;arr.map((element, index, arr) =&amp;gt; { return (new element) });&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3, 4, 5, 6];
let arr2 = arr.map((i) =&amp;gt; i * 2);
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(arr2); // [2, 4, 6, 8, 10, 12]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;첫 번째 출력 : &lt;code&gt;arr&lt;/code&gt;의 원소들의 값은 변하지 않았다. 즉, map은 immutable한 메소드이다.&lt;br&gt;두 번째 출력 : &lt;code&gt;arr2&lt;/code&gt;의 원소들은 &lt;code&gt;arr&lt;/code&gt;의 각각의 원소 &lt;code&gt;i&lt;/code&gt;에 대해 &lt;code&gt;i * 2&lt;/code&gt;한 것이다.&lt;/p&gt;
&lt;h2&gt;reduce()&lt;/h2&gt;
&lt;p&gt;뭔가 말로 설명하기가 굉장히 애매한 메소드.. 이지만, 굉장히 많은 곳에서 사용된다. 예시를 통해 체득하자.&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;arr.reduce(
    (accumulator(누적값), currentValue(현재값), index, arr) =&amp;gt; {
        return (new element)
    }, 초기값);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;초기값 1을 부여했을 때&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3, 4, 5, 6];
let arr2 = arr.reduce((acc, cur, i) =&amp;gt; {
  console.log(acc, cur, i);
  return acc + cur;
  /*
  1 1 0
  2 2 1
  4 3 2
  */
}, 1);
console.log(arr2); // 7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;초기값으로 1을 주고, reducing을 진행한 결과이다. 콜백 내부의 출력을 통해 알 수 있듯이, 1을 초기값으로 Accumulating이 진행되는 모습을 볼 수 있다.&lt;/p&gt;
&lt;h3&gt;초기값이 없을 때&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3, 4, 5, 6];
let arr2 = arr.reduce((acc, cur, i) =&amp;gt; {
  console.log(acc, cur, i);
  return acc + cur;
  /*
  1 2 1
  3 3 2
  */
});
console.log(arr2); // 6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;초기값을 주지 않으면 기본적으로 0이 초기값이다. 이 경우, 콜백 내부의 출력에서는 초기값의 Accumulating 과정은 없으므로 출력되지 않는다.&lt;/p&gt;
&lt;p&gt;reduce() 콜백 내부에서의 출력을 보면 다음 acc의 값이 현재 acc의 값과 cur이 더해져 갱신되는 것을 볼 수 있다.&lt;/p&gt;
&lt;h3&gt;활용 예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;let arr = [1, 2, 3];
let arr2 = arr.reduce((acc, cur, i) =&amp;gt; {
  console.log(acc, cur);
  acc.push(cur % 2 ? &amp;#39;Odd Number&amp;#39; : &amp;#39;Even Number&amp;#39;);
  return acc;
  /*
  [] 1
  [ &amp;#39;Odd Number&amp;#39; ] 2
  [ &amp;#39;Odd Number&amp;#39;, &amp;#39;Even Number&amp;#39; ] 3
  */
}, []);
console.log(arr2); // [ &amp;#39;Odd Number&amp;#39;, &amp;#39;Even Number&amp;#39;, &amp;#39;Odd Number&amp;#39; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;초기값을 빈 배열로 할당해준 후, 배열의 원소가 짝수인지, 홀수인지 판단하여 acc의 배열에 push() 해주는 콜백을 받는 reduce()이다. 이 로직은 똑같이 map()으로도 구현할 수 있다.&lt;/p&gt;
&lt;p&gt;콜백 내부의 출력의 양상을 보자.&lt;br&gt;첫 번째 출력에서 acc는 빈 배열, cur는 1이다. cur이 1이고, 1은 홀수이므로, 다음 acc는 &lt;code&gt;Odd Number&lt;/code&gt;라는 문자 1개가 들어 있는 배열이다.&lt;/p&gt;
&lt;p&gt;이렇게 &lt;code&gt;reducer()&lt;/code&gt;는 acc를 계속 cur의 값에 대해 &lt;strong&gt;갱신(누적)&lt;/strong&gt;시켜 리턴해주는 메소드이다.&lt;/p&gt;</description>
      <category>공부/JavaScript</category>
      <category>es6</category>
      <category>EVERY</category>
      <category>filter</category>
      <category>find</category>
      <category>foreach</category>
      <category>javascript</category>
      <category>map</category>
      <category>reduce</category>
      <category>some</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/96</guid>
      <comments>https://hoondev.tistory.com/96#entry96comment</comments>
      <pubDate>Thu, 25 Jun 2020 03:59:34 +0900</pubDate>
    </item>
    <item>
      <title>SW마에스트로 11기 최종 불합격 후기</title>
      <link>https://hoondev.tistory.com/95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-05-18 오후 8.56.19.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zK1Rx/btqEdwVeV6v/F4wDp2UIkVTsykQ2KMOgHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zK1Rx/btqEdwVeV6v/F4wDp2UIkVTsykQ2KMOgHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zK1Rx/btqEdwVeV6v/F4wDp2UIkVTsykQ2KMOgHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzK1Rx%2FbtqEdwVeV6v%2FF4wDp2UIkVTsykQ2KMOgHk%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-05-18 오후 8.56.19.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;757&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소마에 지원하게 되다.&lt;/h3&gt;
&lt;p&gt;소마 지원공고가 뜬게 아마 1월 쯤이었을 것이다. 평소 '나 같은 사람은 소마 힘들겠지'라는 생각으로 지원할 생각도 없었는데, 동기 한 명이 지원한다고 해서 나도 도전해볼까?하다가 지원하였다.&lt;/p&gt;
&lt;p&gt;평소 사소한 일에도 노력을 많이 기울이는 성격이라, 자소서를 쓰는 대에만 2~3주 정도 걸린 것 같다. 소마 붙으신 선배님은 자소서는 잘 안본다고 하셨지만 그래도 부족한 내 실력을 어필할 수 있는 유일한 기회라고 생각했기에 열심히 했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1차 온라인 코딩 테스트&lt;/h3&gt;
&lt;p&gt;정말 알고리즘의 '알'자도 몰랐기에, 친구의 도움을 받아 알고리즘 세계에 입문하게 되었다. 백준 온라인 강의를 이용해 BFS, DFS, DP, 그리디와 같은 기본적인 알고리즘 지식들을 습득하였다.&lt;/p&gt;
&lt;p&gt;처음에는 코딩 테스트가 4월 중순인가 그랬는데, 망할 코로나19로 코딩 테스트를 온라인으로 보게 되었다. 불행 중 다행으로, 내가 평소에 자신있었던 웹과 SQL 문제가 나와서 후딱 맞추고 알고리즘 문제를 봤는데..&lt;/p&gt;
&lt;p&gt;분명 어떻게 해야 하는지는 알겠는데, 내 손이 따라주지를 않았다. 알고리즘 문제를 많이 풀어본 것도 아니었고, 어떤 알고리즘을 써야 빨리 풀릴 지도 몰랐기 때문이다. 그렇게 나는 무조건 불합격이라고 생각하고 마음을 놓고 있을 찰나.. 합격 통지 문자가 왔다..(?)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-05-18 오후 8.54.33.png&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dv59OL/btqEfXjSslT/MxzyKczMOKCUsXxKj9kwu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dv59OL/btqEfXjSslT/MxzyKczMOKCUsXxKj9kwu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dv59OL/btqEfXjSslT/MxzyKczMOKCUsXxKj9kwu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdv59OL%2FbtqEfXjSslT%2FMxzyKczMOKCUsXxKj9kwu1%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-05-18 오후 8.54.33.png&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;694&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2차 온라인 코딩 테스트&lt;/h3&gt;
&lt;p&gt;2차 코딩 테스트까지는 시간이 한 1달 넘게 있었기 때문에 오롯이 코딩 테스트 준비에만 집중할 수 있었다. 매일 백준 문제를 풀고 실버 문제부터 골드 문제까지 열심히 풀었다. 이제 BFS, DFS만 보면 1~2분 만에 풀 수 있는 정도이다. 1달 간의 빡센 여정 끝에 백준 골드4를 찍기도 했다.&lt;/p&gt;
&lt;p&gt;그러나 이 정도의 노력으로는 힘들었는지 코딩 테스트에서 알고리즘 1번 문제밖에 풀어내지 못했다. 1번은 엄청 쉬운 DP였는데, 기본값을 LLONG_MIN이 아니라 0으로 했고.. 2번 문제는 웹이랑 SQL 풀고 나니 10분 남아서 제대로 풀지도 못하고 제출했다.&lt;/p&gt;
&lt;p&gt;이번에도 탈락할 것을 예상했지만, 결과는 합격이었다...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-05-18 오후 10.20.59.png&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeSEeH/btqEepnPJi3/KuqnRPt0wsarT7rlYVKOck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeSEeH/btqEepnPJi3/KuqnRPt0wsarT7rlYVKOck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeSEeH/btqEepnPJi3/KuqnRPt0wsarT7rlYVKOck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeSEeH%2FbtqEepnPJi3%2FKuqnRPt0wsarT7rlYVKOck%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-05-18 오후 10.20.59.png&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;368&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;심층 면접&lt;/h3&gt;
&lt;p&gt;심층 면접은 정말 정말 정말 운이 안좋게도, 필자 빼고 모두 96년생, 95년생이었다.. 그래서 질문 수준도 너무 어려웠고, 갑자기 '분산 컴퓨팅에 대해서 자유롭게 논해보'라길래.. 개 뻘소리를 짓거렸던 기억이 있다.&lt;/p&gt;
&lt;p&gt;그래도 자신감 있게 모든 질문에 먼저 대답하려고 손을 들었고 이 부분에 대해서 어린 나이이지만 가산점을 받지 않을까 기대했다. 그 외의 대부분의 답변에 대해서는 무난하게 했지만, 어린 나이답게 깊이없는 답변에 아마 많이 실망했을 것이라고 생각한다..&lt;/p&gt;
&lt;p&gt;대진운도 안좋았고, 여러모로 모든게 안좋았던 면접이었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최종 불합격&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;IMG_83881DA94E55-1.jpeg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2436&quot; width=&quot;430&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0BAii/btqEgQYRqjK/Uiym3ilratxtC0swE04sCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0BAii/btqEgQYRqjK/Uiym3ilratxtC0swE04sCK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0BAii/btqEgQYRqjK/Uiym3ilratxtC0swE04sCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0BAii%2FbtqEgQYRqjK%2FUiym3ilratxtC0swE04sCK%2Fimg.jpg&quot; data-filename=&quot;IMG_83881DA94E55-1.jpeg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2436&quot; width=&quot;430&quot; height=&quot;NaN&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;기다림에 지쳐 친구들이랑 잠깐 놀러왔는데, 갑자기 문자가 왔다. 기대를 품고 문자를 열었는데 그대로 굳어버렸다.. 너무 오랜 기간 소마만 바라보고 준비해왔기 때문에 그 실망감이 너무 컸었다.&lt;/p&gt;
&lt;p&gt;하지만, 그만큼 내가 부족하고 미숙하다는 것이기에 크게 연연치 않았다.&lt;/p&gt;
&lt;p&gt;소마를 준비하는 과정에서 알고리즘 공부도 해보고, 또 실제 현업 면접을 겪어보기도 하면서 많은 것들을 얻었다고 생각한다. 이제 군대를 어떻게 할지에 대해서 고민해야 한다. 내년에 한 번 더 도전해보고 결정해보는 것도 나쁘지 않은 것 같다.&lt;/p&gt;
&lt;p&gt;많이 실망스러운 결과지만, 인생은 실전이기에.. 내년을 기약하며&lt;/p&gt;</description>
      <category>일상/후기</category>
      <category>SW마에스트로</category>
      <category>최종불합격</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/95</guid>
      <comments>https://hoondev.tistory.com/95#entry95comment</comments>
      <pubDate>Mon, 18 May 2020 22:26:44 +0900</pubDate>
    </item>
    <item>
      <title>4월 22일 공부 계획</title>
      <link>https://hoondev.tistory.com/94</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;복습&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 11053&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 11054&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2565&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 9251&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1912&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 12865&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구현&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 2573&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;BOJ 9019&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/94</guid>
      <comments>https://hoondev.tistory.com/94#entry94comment</comments>
      <pubDate>Wed, 22 Apr 2020 16:37:23 +0900</pubDate>
    </item>
    <item>
      <title>4월 21일 공부 계획</title>
      <link>https://hoondev.tistory.com/93</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;복습&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 2748&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1003&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1904&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 9461&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1149&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1932&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;s&gt;BOJ 2579&lt;/s&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1463&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;s&gt;BOJ 10844&lt;/s&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2156&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 11047&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 11399&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구현&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 1138&lt;/s&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/93</guid>
      <comments>https://hoondev.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 21 Apr 2020 15:17:41 +0900</pubDate>
    </item>
    <item>
      <title>4월 20일 공부 계획</title>
      <link>https://hoondev.tistory.com/92</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;복습&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1436&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1018&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2751&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 10989&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1181&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 10814&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 15649&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 15650&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 15651&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 15652&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 9663&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2580&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구현&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1022&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1051&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 3190 &lt;span style=&quot;color: #ef5369;&quot;&gt;(골드 5 맞냐..?)&lt;/span&gt;&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/92</guid>
      <comments>https://hoondev.tistory.com/92#entry92comment</comments>
      <pubDate>Mon, 20 Apr 2020 16:36:33 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1202 - 보석 도둑 문제풀이</title>
      <link>https://hoondev.tistory.com/91</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;세계적인 도둑 상덕이는 보석점을 털기로 결심했다.&lt;/p&gt;
&lt;p&gt;상덕이가 털 보석점에는 보석이 총 N개 있다. 각 보석은 무게 Mi와 가격 Vi를 가지고 있다. 상덕이는 가방을 K개 가지고 있고, 각 가방에 담을 수 있는 최대 무게는 Ci이다. 가방에는 최대 한 개의 보석만 넣을 수 있다.&lt;/p&gt;
&lt;p&gt;상덕이가 훔칠 수 있는 보석의 최대 가격을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N과 K가 주어진다. (1 &amp;le; N, K &amp;le; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;300,000&lt;/b&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p&gt;다음 N개 줄에는 각 보석의 정보 Mi와 Vi가 주어진다. (0&amp;nbsp;&amp;le; Mi, Vi&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1,000,000&lt;/b&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p&gt;다음 K개 줄에는 가방에 담을 수 있는 최대 무게 Ci가 주어진다. (1 &amp;le; Ci&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100,000,000)&lt;/p&gt;
&lt;p&gt;모든 숫자는 양의 정수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 상덕이가 훔칠 수 있는 보석&amp;nbsp;가격의 합의 최댓값을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;이 문제는 STL의 multiset을 모른다면 꽤 애를 먹을 수 있는 문제이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(자주 사용하는 STL 컨테이너는 다 외워두자..)&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력받은 보석 정보는 보석의 가치에 대한 내림차순으로 우선순위 큐에 담아둔다.&lt;/li&gt;
&lt;li&gt;multiset을 이용하여 가방의 최대 무게 정보를 저장한다. 이때, multiset의 특징에 따라 오름차순 정렬된다.&lt;/li&gt;
&lt;li&gt;우선순위 큐에 있는 원소가 하나도 없을 때까지 아래 과정을 진행한다.
&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;
&lt;li&gt;우선순위 큐 최상단에 있는 보석의 무게를 m이라고 할 때, m 이상의 무게를 담을 수 있는 가방들 중 첫 번째 것을 찾는다.&lt;/li&gt;
&lt;li&gt;찾았을 경우, 담은 보석의 가치 총합(result)에 우선순위 큐 최상단에 있는 보석의 가치 v를 더해준다.&lt;/li&gt;
&lt;li&gt;그리고, 사용한 가방은 multiset에서 제거(erase)해준다. -&amp;gt; 시간복잡도&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; logn&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;보석을 가방에 담든, 담지 않든 최상단의 보석은 사용했거나 더 이상 사용하지 않을 것이므로 우선순위 큐에서 제거해준다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587312640675&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;set&amp;gt;
#include &amp;lt;queue&amp;gt;
#define ULL unsigned long long
using namespace std;

priority_queue&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; pq;
multiset&amp;lt;int&amp;gt; ms;

ULL result = 0;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, k;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; k;
    for (int i = 0; i &amp;lt; n; i++) {
        int m, v;
        cin &amp;gt;&amp;gt; m &amp;gt;&amp;gt; v;
        pq.push({v, m});
    }
    for (int i = 0; i &amp;lt; k; i++) {
        int c;
        cin &amp;gt;&amp;gt; c;
        ms.insert(c);
    }

    while (!pq.empty()) {
        int v = pq.top().first;
        int m = pq.top().second;

        auto it = ms.lower_bound(m);
        if (it != ms.end()) {
            result += v;
            ms.erase(it);
        }

        pq.pop();
    }
    cout &amp;lt;&amp;lt; result;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>그리디</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/91</guid>
      <comments>https://hoondev.tistory.com/91#entry91comment</comments>
      <pubDate>Mon, 20 Apr 2020 01:17:03 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 2003 - 수들의 합 2 문제풀이</title>
      <link>https://hoondev.tistory.com/90</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;N개의 수로 된 수열 A[1], A[2], &amp;hellip;, A[N] 이 있다. 이 수열의 i번째 수부터 j번째 수까지의 합 A[i]+A[i+1]+&amp;hellip;+A[j-1]+A[j]가 M이 되는 경우의 수를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N(1&amp;le;N&amp;le;10,000), M(1&amp;le;M&amp;le;300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], &amp;hellip;, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 경우의 수를 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;대표적인 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;투 포인터 알고리즘(Two Pointers Algorithm)&lt;/b&gt; &lt;/span&gt;문제이다. 정말 딱 투 포인터 알고리즘만 쓰면 풀리는 문제.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;알고리즘 배우기&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://m.blog.naver.com/kks227/220795165570&quot;&gt;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window)&lt;/a&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1587297032525&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window) (수정: 2019-09-09)&quot; data-og-description=&quot;조금 성향이 비슷하다고 생각하는 기법 2개를 함께 쓰려 합니다.첫 번째로 소개해드릴 기법은 투 포인터(tw...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/kks227/220795165570&quot; data-og-url=&quot;https://blog.naver.com/kks227/220795165570&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dbk38Q/hyFIY2c6nc/svT5kui34aY35PtObWKS5k/img.png?width=651&amp;amp;height=148&amp;amp;face=0_0_651_148,https://scrap.kakaocdn.net/dn/nkiVv/hyFKpcP7zV/W0G9CNgKJb4YAXhekOnKb1/img.png?width=560&amp;amp;height=336&amp;amp;face=0_0_560_336&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/kks227/220795165570&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/kks227/220795165570&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dbk38Q/hyFIY2c6nc/svT5kui34aY35PtObWKS5k/img.png?width=651&amp;amp;height=148&amp;amp;face=0_0_651_148,https://scrap.kakaocdn.net/dn/nkiVv/hyFKpcP7zV/W0G9CNgKJb4YAXhekOnKb1/img.png?width=560&amp;amp;height=336&amp;amp;face=0_0_560_336');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window) (수정: 2019-09-09)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;조금 성향이 비슷하다고 생각하는 기법 2개를 함께 쓰려 합니다.첫 번째로 소개해드릴 기법은 투 포인터(tw...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;관련 문제&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2020/04/19 - [알고리즘/문제풀이] - BOJ 1806 - 부분합 문제풀이&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1587296996769&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;BOJ 1806 - 부분합 문제풀이&quot; data-og-description=&quot;문제를 읽고 이해하기 10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오..&quot; data-og-host=&quot;hoondev.tistory.com&quot; data-og-source-url=&quot;https://hoondev.tistory.com/88&quot; data-og-url=&quot;https://hoondev.tistory.com/88&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PrhHU/hyFKkin5Zw/CjHd1lmSS8BotJuqnmffC1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/nDHVa/hyFI1EKLV6/Obtstx6JSImKVvQgwAJqm0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hoondev.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hoondev.tistory.com/88&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PrhHU/hyFKkin5Zw/CjHd1lmSS8BotJuqnmffC1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/nDHVa/hyFI1EKLV6/Obtstx6JSImKVvQgwAJqm0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;BOJ 1806 - 부분합 문제풀이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문제를 읽고 이해하기 10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;hoondev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587296931836&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int A[10000];

int main() {
    int n, m, ans = 0;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;

    for (int i = 0; i &amp;lt; n; i++) cin &amp;gt;&amp;gt; A[i];

    int s = 0, e = 0, psum = 0;
    while (1) {
        if (psum &amp;gt;= m) psum -= A[s++];
        else if (e == n) break;
        else psum += A[e++];

        if (psum == m) ans++;
    }
    cout &amp;lt;&amp;lt; ans;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>투포인터</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/90</guid>
      <comments>https://hoondev.tistory.com/90#entry90comment</comments>
      <pubDate>Sun, 19 Apr 2020 20:50:45 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 10942 - 팰린드롬? 문제풀이</title>
      <link>https://hoondev.tistory.com/89</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;명우는 홍준이와 함께 팰린드롬 놀이를 해보려고 한다.&lt;/p&gt;
&lt;p&gt;먼저, 홍준이는 자연수 N개를 칠판에 적는다. 그 다음, 명우에게 질문을 총 M번 한다.&lt;/p&gt;
&lt;p&gt;각 질문은 두 정수 S와 E(1 &amp;le; S &amp;le; E &amp;le; N)로 나타낼 수 있으며, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;S번째 수부터 E번째 까지&amp;nbsp;수가 팰린드롬을 이루는지&lt;/b&gt;&lt;/span&gt;를 물어보며, 명우는 각 질문에 대해 팰린드롬이다 또는 아니다를 말해야 한다.&lt;/p&gt;
&lt;p&gt;예를 들어, 홍준이가 칠판에 적은 수가 1, 2, 1, 3, 1, 2, 1라고 하자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;S = 1, E = 3인 경우 1, 2, 1은 팰린드롬이다.&lt;/li&gt;
&lt;li&gt;S = 2, E = 5인 경우 2, 1, 3, 1은 팰린드롬이 아니다.&lt;/li&gt;
&lt;li&gt;S = 3, E = 3인 경우 1은 팰린드롬이다.&lt;/li&gt;
&lt;li&gt;S = 5, E = 7인 경우 1, 2, 1은 팰린드롬이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자연수 N개와 질문 M개가 모두 주어졌을 때, 명우의 대답을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 수열의 크기 N (1 &amp;le; N &amp;le; 2,000)이 주어진다.&lt;/p&gt;
&lt;p&gt;둘째 줄에는 홍준이가 칠판에 적은 수 N개가 순서대로 주어진다. 칠판에 적은 수는 100,000보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;p&gt;셋째 줄에는 홍준이가 한 질문의 개수 M (1 &amp;le; M &amp;le; 1,000,000)이 주어진다.&lt;/p&gt;
&lt;p&gt;넷째 줄부터 M개의 줄에는 홍준이가 명우에게 한 질문 S와 E가 한 줄에 하나씩 주어진다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;총 M개의 줄에 걸쳐 홍준이의 질문에 대한 명우의 답을 입력으로 주어진 순서에 따라서 출력한다. 팰린드롬인 경우에는 1, 아닌 경우에는 0을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;지금까지의 DP는 입력을 먼저 받은 후, 그 입력받은 수들에 대해서 DP를 진행했다면, 이 문제에서는 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;입력 하나가 들어올 때마다 DP 처리&lt;/b&gt;&lt;/span&gt;를 해주는 방식으로 한다.&lt;/p&gt;
&lt;p&gt;입력받은 수는 0번째 인덱스(i)부터 n - 1번째 인덱스까지 arr[i]에 저장한다. 입력이 들어올 때마다, 아래와 같은 알고리즘을 시행한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;i번째부터 i번째 범위의 수들은 Palindrome이다. -&amp;gt; isPalindrome[i][i] = true (자기 자신밖에 없으므로)&lt;/li&gt;
&lt;li&gt;i 인덱스 이전의 수 k에 대해서 arr[k] == arr[i]일 때 (두 수가 같을 때), Palindrome[k][i]가 true인지 false인지 결정하려고 한다.&lt;/li&gt;
&lt;li&gt;k - 1 인덱스부터 i - 1 인덱스까지의 수가 Palindrome이면 arr[k] == arr[i]인 k와 i에 대해서, k 인덱스부터 i 인덱스까지의 수도 Palindorme이다.&lt;/li&gt;
&lt;li&gt;만약 i - k가 2 이하의 수면 arr[k] == arr[i]인 k와 i에 대해서, k 인덱스부터 i 인덱스까지의 수는 항상 Palindrome이다.&lt;br /&gt;(예: 1 2 1 -&amp;gt; Palindrome, 1 1 -&amp;gt; Palindrome)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이렇게 isPalindrome을 모두 구한 뒤, 입력받은 s와 e에 대해 isPalindrome[s - 1][e - 1]을 출력하면 된다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587293608844&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int arr[2000];
bool isPalindrome[2000][2000];

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; n; i++) {
        cin &amp;gt;&amp;gt; arr[i];
        isPalindrome[i][i] = true;
        for (int k = i - 1; k &amp;gt;= 0; k--) {
            if (arr[k] == arr[i]) {
                if (i - k &amp;gt; 2) {
                    if (!isPalindrome[k + 1][i - 1]) continue;
                }
                isPalindrome[k][i] = true;
            }
        }
    }
    cin &amp;gt;&amp;gt; m;
    while (m--) {
        int s, e;
        cin &amp;gt;&amp;gt; s &amp;gt;&amp;gt; e;
        cout &amp;lt;&amp;lt; isPalindrome[s - 1][e - 1] &amp;lt;&amp;lt; '\n';
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>dp</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/89</guid>
      <comments>https://hoondev.tistory.com/89#entry89comment</comments>
      <pubDate>Sun, 19 Apr 2020 20:03:17 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1806 - 부분합 문제풀이</title>
      <link>https://hoondev.tistory.com/88</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;10,000 이하의 자연수로 이루어진 길이 N짜리&amp;nbsp;수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N (10 &amp;le; N &amp;lt; 100,000)과&amp;nbsp;S (0 &amp;lt; S &amp;le; 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;이 문제는 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;투 포인터 알고리즘(Two Pointers Algorithm)&lt;/b&gt;&lt;/span&gt;을 이용한 대표적인 문제다. 이 문제를 처음 시도할 때 아무것도 모른 채 접근했기 때문에 너무 힘들었는데, 역시 30분이 걸려도 갈피를 못 잡겠으면 구글링이 답이라는 것을 깨달았다..&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://m.blog.naver.com/kks227/220795165570&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1587289379512&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window) (수정: 2019-09-09)&quot; data-og-description=&quot;조금 성향이 비슷하다고 생각하는 기법 2개를 함께 쓰려 합니다.첫 번째로 소개해드릴 기법은 투 포인터(tw...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/kks227/220795165570&quot; data-og-url=&quot;https://blog.naver.com/kks227/220795165570&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dbk38Q/hyFIY2c6nc/svT5kui34aY35PtObWKS5k/img.png?width=651&amp;amp;height=148&amp;amp;face=0_0_651_148,https://scrap.kakaocdn.net/dn/nkiVv/hyFKpcP7zV/W0G9CNgKJb4YAXhekOnKb1/img.png?width=560&amp;amp;height=336&amp;amp;face=0_0_560_336&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/kks227/220795165570&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/kks227/220795165570&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dbk38Q/hyFIY2c6nc/svT5kui34aY35PtObWKS5k/img.png?width=651&amp;amp;height=148&amp;amp;face=0_0_651_148,https://scrap.kakaocdn.net/dn/nkiVv/hyFKpcP7zV/W0G9CNgKJb4YAXhekOnKb1/img.png?width=560&amp;amp;height=336&amp;amp;face=0_0_560_336');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window) (수정: 2019-09-09)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;조금 성향이 비슷하다고 생각하는 기법 2개를 함께 쓰려 합니다.첫 번째로 소개해드릴 기법은 투 포인터(tw...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;위 문서를 읽고 나면 쉽게 풀 수 있을 것이다. 다른 점이라면, 문제에서 &lt;span&gt;그 합이 S 이상이 되는 것들 중, 가장 짧은 것의 길이를 구한다는 점이다. 이걸 깨닫지 못해서 6번이나 재시도했던 경험이 있다..ㅠㅠ&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587289219294&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;climits&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int arr[100000];
int shortest = INT_MAX;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, s;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; s;
    for (int i = 0; i &amp;lt; n; i++) cin &amp;gt;&amp;gt; arr[i];

    int start = 0, end = 0, result = 0;
    while (true) {
        if (result &amp;gt;= s) { result -= arr[start++]; }
        else if (end == n) break;
        else result += arr[end++];

        if (result &amp;gt;= s) shortest = min(end - start, shortest);
    }
    cout &amp;lt;&amp;lt; ((shortest == INT_MAX) ? 0 : shortest);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>투포인터</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/88</guid>
      <comments>https://hoondev.tistory.com/88#entry88comment</comments>
      <pubDate>Sun, 19 Apr 2020 18:44:54 +0900</pubDate>
    </item>
    <item>
      <title>4월 19일 공부 계획</title>
      <link>https://hoondev.tistory.com/87</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적 계획법&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 10942&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;알고리즘 스터디&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 14731&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 7795&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그리디&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1202&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;BOJ 1339&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;투 포인터 알고리즘&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1806&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2003&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기타&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;자료구조 과제 3 제출&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/87</guid>
      <comments>https://hoondev.tistory.com/87#entry87comment</comments>
      <pubDate>Sun, 19 Apr 2020 02:00:55 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 12015 - 가장 긴 증가하는 부분 수열 2 문제풀이</title>
      <link>https://hoondev.tistory.com/86</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;수열 A가 주어졌을 때, 가장 긴 증가하는&amp;nbsp;부분&amp;nbsp;수열을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p&gt;예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&amp;nbsp;수열은&amp;nbsp;A = {&lt;b&gt;10&lt;/b&gt;,&amp;nbsp;&lt;b&gt;20&lt;/b&gt;, 10,&amp;nbsp;&lt;b&gt;30&lt;/b&gt;, 20,&amp;nbsp;&lt;b&gt;50&lt;/b&gt;} 이고, 길이는 4이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 수열 A의 크기 N (1 &amp;le; N &amp;le; 1,000,000)이 주어진다.&lt;/p&gt;
&lt;p&gt;둘째&amp;nbsp;줄에는&amp;nbsp;수열&amp;nbsp;A를&amp;nbsp;이루고&amp;nbsp;있는&amp;nbsp;A&lt;sub&gt;i&lt;/sub&gt;가&amp;nbsp;주어진다.&amp;nbsp;(1&amp;nbsp;&amp;le;&amp;nbsp;A&lt;sub&gt;i&lt;/sub&gt;&amp;nbsp;&amp;le;&amp;nbsp;1,000,000)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;BOJ 11053 - 가장 긴 증가하는 부분 수열 문제에서는 N의 범위가 작기 때문에 DP로 풀 수 있었지만 이 문제는 N의 범위가 100만으로 엄청 커져버려서 시간 제한 안에 풀 수 없다.&lt;/p&gt;
&lt;p&gt;이 문제를 통해 범위가 바뀌면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;알고리즘 자체가 바뀌어야 할 수도 있다&lt;/b&gt;&lt;/span&gt;는 것을 알게 되었다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;순차적으로 입력되는 수에 대해서&lt;/b&gt;&lt;/span&gt; 알고리즘은 아래와 같이 구성된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력받은 수가 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;벡터의 맨 뒤에 있는 수&lt;/b&gt;&lt;/span&gt;보다 클 경우 수를 맨 뒤에 집어 넣는다.&lt;/li&gt;
&lt;li&gt;그렇지 않을 경우, 이분 탐색의 lower_bound를 이용하여 &lt;b&gt;입력받은 수보다 크거나 같은 값이 처음 위치한 곳(lower_bound의 리턴값)&lt;/b&gt;에 입력 값을 대치시킨다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이를 구현하기 위해 처음 climits 헤더에 있는 INT_MAX값(2^31 - 1)을 벡터에 추가한다. 이는 처음 입력받은 수에 대해서 따로 for문 내부에서 예외처리를 하지 않고 lower_bound를 통해 첫 인덱스에 값을 대입하기 위함이다.&lt;/p&gt;
&lt;p&gt;그리고, 이후에 들어온 입력값에 대해 알고리즘을 시행한다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2020/04/03 - [언어/C, C++] - [C++ STL] upper_bound, lower_bound 알아보기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1587227714872&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[C++ STL] upper_bound, lower_bound 알아보기&quot; data-og-description=&quot;lower_bound 개요 특징 이진 탐색(binary_search)의 근간이 된다. algorithm 헤더에 포함되어 있다. 설명 이진 탐색 기반의 탐색이므로, 배열 또는 리스트가 오름차순 정렬되어 있어야 한다. 찾으려고 하는 key 값..&quot; data-og-host=&quot;hoondev.tistory.com&quot; data-og-source-url=&quot;https://hoondev.tistory.com/53&quot; data-og-url=&quot;https://hoondev.tistory.com/53&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BCCQl/hyFIYf8Uuz/eAwIeYgr3hNhKXAy2KsOc1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/lezIu/hyFI1RtF4w/RKJH1Awr47Za4LWjPDWAk0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hoondev.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hoondev.tistory.com/53&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BCCQl/hyFIYf8Uuz/eAwIeYgr3hNhKXAy2KsOc1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/lezIu/hyFI1RtF4w/RKJH1Awr47Za4LWjPDWAk0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[C++ STL] upper_bound, lower_bound 알아보기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;lower_bound 개요 특징 이진 탐색(binary_search)의 근간이 된다. algorithm 헤더에 포함되어 있다. 설명 이진 탐색 기반의 탐색이므로, 배열 또는 리스트가 오름차순 정렬되어 있어야 한다. 찾으려고 하는 key 값..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;hoondev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587226889145&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;climits&amp;gt;
using namespace std;

vector&amp;lt;int&amp;gt; v;

int main() {
    int n;
    cin &amp;gt;&amp;gt; n;
    v.push_back(INT_MAX);
    for (int i = 0; i &amp;lt; n; i++) {
        int input;
        cin &amp;gt;&amp;gt; input;
        if (v.back() &amp;lt; input) {
            v.push_back(input);
        } else {
            *lower_bound(v.begin(), v.end(), input) = input;
        }
    }
    cout &amp;lt;&amp;lt; v.size();
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>이분탐색</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/86</guid>
      <comments>https://hoondev.tistory.com/86#entry86comment</comments>
      <pubDate>Sun, 19 Apr 2020 01:35:17 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1074 - Z 문제풀이</title>
      <link>https://hoondev.tistory.com/85</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;한수는 2차원 배열 (항상 2^N * 2^N 크기이다)을 Z모양으로 탐색하려고 한다. 예를 들어, 2*2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZiGlb/btqDx6BElhL/0THeiHy1J4LuDxKolrdGa0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZiGlb/btqDx6BElhL/0THeiHy1J4LuDxKolrdGa0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZiGlb/btqDx6BElhL/0THeiHy1J4LuDxKolrdGa0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZiGlb%2FbtqDx6BElhL%2F0THeiHy1J4LuDxKolrdGa0%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.&lt;/p&gt;
&lt;p&gt;다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bV8ook/btqDxuweL4G/MN697kXML779vvG4kunne1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV8ook/btqDxuweL4G/MN697kXML779vvG4kunne1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV8ook/btqDxuweL4G/MN697kXML779vvG4kunne1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbV8ook%2FbtqDxuweL4G%2FMN697kXML779vvG4kunne1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p&gt;다음 그림은 N=3일 때의 예이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8NUdm/btqDyFw1HgZ/uCaZKnjLUjF9IJghLKTLp0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8NUdm/btqDyFw1HgZ/uCaZKnjLUjF9IJghLKTLp0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8NUdm/btqDyFw1HgZ/uCaZKnjLUjF9IJghLKTLp0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8NUdm%2FbtqDyFw1HgZ%2FuCaZKnjLUjF9IJghLKTLp0%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 문제의 정답을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;전형적인 분할 정복 문제이지만, 그 구현부가 조금 독특하다는 점이 특징이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;주어진 길이가 2일 때까지 계속 4등분한다. 4등분할 때 순서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래 순서(Z)&lt;/b&gt;&lt;/span&gt;를 꼭 지켜주어야 한다.&lt;/li&gt;
&lt;li&gt;주어진 길이가 2일 경우, 아까 언급한 순서를 지켜 &lt;span style=&quot;color: #333333;&quot;&gt;왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래 순서로 방문한다. 방문할 때마다 cnt 값을 1씩 증가시키고, 만약 좌표가 (r, c)일 경우 진행을 중단한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587214060634&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cmath&amp;gt;
using namespace std;

typedef struct {
    int y, x;
} Position;

Position pos[4] = {
        {0, 0},
        {0, 1},
        {1, 0},
        {1, 1}
};

int n, r, c, cnt;

bool divide_and_conquer(int y, int x, int length) {
    if (length != 2) {
        if (divide_and_conquer(y, x, length / 2)) return true;
        if (divide_and_conquer(y, x + length / 2, length / 2)) return true;
        if (divide_and_conquer(y + length / 2, x, length / 2)) return true;
        if (divide_and_conquer(y + length / 2, x + length / 2, length / 2)) return true;
        return false;
    }
    for (auto &amp;amp; p : pos) {
        int now_y = y + p.y;
        int now_x = x + p.x;
        cnt++;
        if (now_y == r &amp;amp;&amp;amp; now_x == c) return true;
    }
    return false;
}

int main() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; r &amp;gt;&amp;gt; c;
    divide_and_conquer(0, 0, pow(2, n));
    cout &amp;lt;&amp;lt; cnt - 1;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>분할정복</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/85</guid>
      <comments>https://hoondev.tistory.com/85#entry85comment</comments>
      <pubDate>Sat, 18 Apr 2020 21:52:06 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 7579 - 앱 문제풀이</title>
      <link>https://hoondev.tistory.com/84</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;우리는 스마트폰을 사용하면서 여러 가지 앱(App)을 실행하게 된다. 대개의 경우 화면에 보이는 &amp;lsquo;실행 중&amp;rsquo;인 앱은 하나뿐이지만 보이지 않는 상태로 많은 앱이 '활성화'되어 있다. 앱들이 활성화 되어 있다는 것은 화면에 보이지 않더라도 메인 메모리에 직전의 상태가 기록되어 있는 것을 말한다. 현재 실행 중이 아니더라도 이렇게 메모리에 남겨두는 이유는 사용자가 이전에 실행하던 앱을 다시 불러올 때에 직전의 상태를 메인 메모리로부터 읽어 들여 실행 준비를 빠르게 마치기 위해서이다.&lt;/p&gt;
&lt;p&gt;하지만 스마트폰의 메모리는 제한적이기 때문에 한번이라도 실행했던 모든 앱을 활성화된 채로 메인 메모리에 남겨두다 보면 메모리 부족 상태가 오기 쉽다. 새로운 앱을 실행시키기 위해 필요한 메모리가 부족해지면 스마트폰의 운영체제는 활성화 되어 있는 앱들 중 몇 개를 선택하여 메모리로부터 삭제하는 수밖에 없다. 이러한 과정을 앱의 &amp;lsquo;비활성화&amp;rsquo;라고 한다.&lt;/p&gt;
&lt;p&gt;메모리 부족 상황에서 활성화 되어 있는 앱들을 무작위로 필요한 메모리만큼 비활성화 하는 것은 좋은 방법이 아니다. 비활성화된 앱들을 재실행할 경우 그만큼 시간이 더 필요하기 때문이다. 여러분은 이러한 앱의 비활성화 문제를 스마트하게 해결하기 위한 프로그램을 작성해야 한다&lt;/p&gt;
&lt;p&gt;현재&amp;nbsp;N개의&amp;nbsp;앱,&amp;nbsp;A&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;A&lt;sub&gt;N&lt;/sub&gt;이&amp;nbsp;활성화&amp;nbsp;되어&amp;nbsp;있다고&amp;nbsp;가정하자.&amp;nbsp;이들&amp;nbsp;앱&amp;nbsp;A&lt;sub&gt;i&lt;/sub&gt;는&amp;nbsp;각각&amp;nbsp;m&lt;sub&gt;i&lt;/sub&gt;&amp;nbsp;바이트만큼의&amp;nbsp;메모리를&amp;nbsp;사용하고&amp;nbsp;있다.&amp;nbsp;또한,&amp;nbsp;앱&amp;nbsp;A&lt;sub&gt;i&lt;/sub&gt;를&amp;nbsp;비활성화한&amp;nbsp;후에&amp;nbsp;다시&amp;nbsp;실행하고자&amp;nbsp;할&amp;nbsp;경우,&amp;nbsp;추가적으로&amp;nbsp;들어가는&amp;nbsp;비용(시간&amp;nbsp;등)을&amp;nbsp;수치화&amp;nbsp;한&amp;nbsp;것을&amp;nbsp;c&lt;sub&gt;i&lt;/sub&gt;&amp;nbsp;라고&amp;nbsp;하자.&amp;nbsp;이러한&amp;nbsp;상황에서&amp;nbsp;사용자가&amp;nbsp;새로운&amp;nbsp;앱&amp;nbsp;B를&amp;nbsp;실행하고자&amp;nbsp;하여,&amp;nbsp;추가로&amp;nbsp;M&amp;nbsp;바이트의&amp;nbsp;메모리가&amp;nbsp;필요하다고&amp;nbsp;하자.&amp;nbsp;즉,&amp;nbsp;현재&amp;nbsp;활성화&amp;nbsp;되어&amp;nbsp;있는&amp;nbsp;앱&amp;nbsp;A&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;A&lt;sub&gt;N&lt;/sub&gt;&amp;nbsp;중에서&amp;nbsp;몇&amp;nbsp;개를&amp;nbsp;비활성화&amp;nbsp;하여&amp;nbsp;M&amp;nbsp;바이트&amp;nbsp;이상의&amp;nbsp;메모리를&amp;nbsp;추가로&amp;nbsp;확보해야&amp;nbsp;하는&amp;nbsp;것이다.&amp;nbsp;여러분은&amp;nbsp;그&amp;nbsp;중에서&amp;nbsp;비활성화&amp;nbsp;했을&amp;nbsp;경우의&amp;nbsp;비용&amp;nbsp;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;c&lt;sub&gt;i&lt;/sub&gt;의&amp;nbsp;합을&amp;nbsp;최소화&lt;/b&gt;&lt;/span&gt;하여&amp;nbsp;필요한&amp;nbsp;메모리&amp;nbsp;M&amp;nbsp;바이트를&amp;nbsp;확보하는&amp;nbsp;방법을&amp;nbsp;찾아야&amp;nbsp;한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;입력은&amp;nbsp;3줄로&amp;nbsp;이루어져&amp;nbsp;있다.&amp;nbsp;첫&amp;nbsp;줄에는&amp;nbsp;정수&amp;nbsp;N과&amp;nbsp;M이&amp;nbsp;공백문자로&amp;nbsp;구분되어&amp;nbsp;주어지며,&amp;nbsp;둘째&amp;nbsp;줄과&amp;nbsp;셋째&amp;nbsp;줄에는&amp;nbsp;각각&amp;nbsp;N개의&amp;nbsp;정수가&amp;nbsp;공백문자로&amp;nbsp;구분되어&amp;nbsp;주어진다.&amp;nbsp;둘째&amp;nbsp;줄의&amp;nbsp;N개의&amp;nbsp;정수는&amp;nbsp;현재&amp;nbsp;활성화&amp;nbsp;되어&amp;nbsp;있는&amp;nbsp;앱&amp;nbsp;A&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;A&lt;sub&gt;N&lt;/sub&gt;이&amp;nbsp;사용&amp;nbsp;중인&amp;nbsp;메모리의&amp;nbsp;바이트&amp;nbsp;수인&amp;nbsp;m&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;m&lt;sub&gt;N&lt;/sub&gt;을&amp;nbsp;의미하며,&amp;nbsp;셋째&amp;nbsp;줄의&amp;nbsp;정수는&amp;nbsp;각&amp;nbsp;앱을&amp;nbsp;비활성화&amp;nbsp;했을&amp;nbsp;경우의&amp;nbsp;비용&amp;nbsp;c&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;c&lt;sub&gt;N&lt;/sub&gt;을&amp;nbsp;의미한다&lt;/p&gt;
&lt;p&gt;단,&amp;nbsp;1&amp;nbsp;&amp;le;&amp;nbsp;N&amp;nbsp;&amp;le;&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;100&lt;/b&gt;&lt;/span&gt;,&amp;nbsp;1&amp;nbsp;&amp;le;&amp;nbsp;M&amp;nbsp;&amp;le;&amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;10,000,000&lt;/b&gt;&lt;/span&gt;이며,&amp;nbsp;1&amp;nbsp;&amp;le;&amp;nbsp;m&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;m&lt;sub&gt;N&lt;/sub&gt;&amp;nbsp;&amp;le;&amp;nbsp;10,000,000을&amp;nbsp;만족한다.&amp;nbsp;또한,&amp;nbsp;0&amp;nbsp;&amp;le;&amp;nbsp;c&lt;sub&gt;1&lt;/sub&gt;,&amp;nbsp;...,&amp;nbsp;c&lt;sub&gt;N&lt;/sub&gt;&amp;nbsp;&amp;le;&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;100&lt;/b&gt;&lt;/span&gt;이고,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;M&amp;nbsp;&amp;le;&amp;nbsp;m&lt;sub&gt;1&lt;/sub&gt;&amp;nbsp;+&amp;nbsp;m&lt;sub&gt;2&lt;/sub&gt;&amp;nbsp;+&amp;nbsp;...&amp;nbsp;+&amp;nbsp;m&lt;sub&gt;N&lt;/sub&gt;&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;필요한 메모리 M 바이트를 확보하기 위한 앱 비활성화의 최소의 비용을 계산하여 한 줄에 출력해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;이 문제는 DP의 냅색 알고리즘을 이용해 풀면 된다. 냅색 문제 중 개인적으로 조금 어려웠던 문제였다. 다른 블로그를 보니, 1차원 DP 배열로도 문제를 푸는 사람도 있었는데, 필자는 그 방식이 더 어려워서 2차원 DP 배열로 풀었다.&lt;/p&gt;
&lt;pre id=&quot;code_1587210234321&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// i는 i 인덱스까지의 원소를 사용한다는 의미
// j는 사용한 총 비용
dp[i][j] = max(activate[i] + dp[i - 1][j - resume[i]], dp[i][j])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;냅색 알고리즘의 원리를 이용한다. i는 1번째부터 i번째 앱들 중에서 &lt;b&gt;임의의 개수&lt;/b&gt;를 &lt;b&gt;비활성화하겠다&lt;/b&gt;는 의미이고, j는 &lt;b&gt;앱을 재실행했을 때 드는 비용의 합&lt;/b&gt;이 j라는 의미이다.&lt;/p&gt;
&lt;p&gt;dp[i][j]는 1번째부터 i번째 앱들 중에서 임의의 개수를 비활성화하여 그 비활성화된 앱을 재실행했을 때 드는 총 비용이 j가 될 때, 확보한 메모리 값의 합을 의미한다.&lt;/p&gt;
&lt;p&gt;따라서 우리가 구해야하는 값은 1번째부터 N번째 앱들 중에서 임의의 개수를 비활성화하였을 때, 확보한 메모리 값의 합이 M일 때의 앱을 재실행했을 때 드는 비용의 합이 정답이다.&lt;/p&gt;
&lt;p&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://hoondev.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2020/04/09 - [알고리즘/문제풀이] - BOJ 12865 - 평범한 배낭(냅색 알고리즘) 문제풀이&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1587210161763&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;BOJ 12865 - 평범한 배낭(냅색 알고리즘) 문제풀이&quot; data-og-description=&quot;문제를 읽고 이해하기 이 문제는 아주 평범한 배낭 에 관한 문제이다. 한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다..&quot; data-og-host=&quot;hoondev.tistory.com&quot; data-og-source-url=&quot;https://hoondev.tistory.com/74&quot; data-og-url=&quot;https://hoondev.tistory.com/74&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yUktv/hyFHKjfrtS/nf5JkV1ZhKK2LPNOM106l1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/NkXzO/hyFIYmDqUW/hGS67dc47gyAsTApyvoyY0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hoondev.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hoondev.tistory.com/74&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yUktv/hyFHKjfrtS/nf5JkV1ZhKK2LPNOM106l1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/NkXzO/hyFIYmDqUW/hGS67dc47gyAsTApyvoyY0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;BOJ 12865 - 평범한 배낭(냅색 알고리즘) 문제풀이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문제를 읽고 이해하기 이 문제는 아주 평범한 배낭 에 관한 문제이다. 한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;hoondev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587206389717&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int n, m;

int activate[101];
int resume[101];

int dp[101][10001];

int main() {
    int sum = 0;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;

    for (int i = 1; i &amp;lt;= n; i++) cin &amp;gt;&amp;gt; activate[i];
    for (int i = 1; i &amp;lt;= n; i++) { cin &amp;gt;&amp;gt; resume[i]; sum += resume[i]; }

    for (int i = 1; i &amp;lt;= n; i++) {
        for (int j = 0; j &amp;lt;= sum; j++) {
            dp[i][j] = dp[i - 1][j];
            if (j - resume[i] &amp;gt;= 0)
                dp[i][j] = max(activate[i] + dp[i - 1][j - resume[i]], dp[i][j]);
        }
    }

    for (int i = 0; i &amp;lt;= sum; i++) {
        if (dp[n][i] &amp;gt;= m) {
            cout &amp;lt;&amp;lt; i;
            break;
        }
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>dp</category>
      <category>냅색</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/84</guid>
      <comments>https://hoondev.tistory.com/84#entry84comment</comments>
      <pubDate>Sat, 18 Apr 2020 20:59:36 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 12852 - 1로 만들기 2 문제풀이</title>
      <link>https://hoondev.tistory.com/83</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;X가 3으로 나누어 떨어지면, 3으로 나눈다.&lt;/li&gt;
&lt;li&gt;X가 2로 나누어 떨어지면, 2로 나눈다.&lt;/li&gt;
&lt;li&gt;1을 뺀다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;정수 N이 주어졌을 때,&amp;nbsp;위와 같은 연산 세 개를 적절히 사용해서&amp;nbsp;1을 만들려고 한다. &lt;b&gt;연산을 사용하는 횟수의 최솟값&lt;/b&gt;을 출력하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 1보다 크거나 같고, 10의 6제곱 보다 작거나 같은 자연수 N이 주어진다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.&lt;/p&gt;
&lt;p&gt;둘째 줄에는 N을 1로 만드는 방법에 포함되어 있는 수를 공백으로 구분해서 순서대로 출력한다. 정답이 여러 가지인 경우에는 아무거나 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고로 이 문제는 clang 컴파일러에서 실행할 경우 메모리 오류가 발생합니다..!&lt;/blockquote&gt;
&lt;p&gt;DP를 이용해 문제를 풀 수 있다. DP 구현부는 코드를 보면 이해할 수 있으므로 따로 설명하지 않고, 최소 연산으로 1을 만드는 데까지의 과정을 저장하는 방법에 대해서만 설명하겠다. (중요함)&lt;/p&gt;
&lt;p&gt;그 과정은 procedure라는 이름의 배열에 저장하는데, 배열의 인덱스는 현재의 값을 의미하고, 그 배열의 값은 최소 연산을 구현하는 다음 값을 의미한다. 즉, 배열의 값은&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(현재의 값 - 1), (현재의 값 / 2), (현재의 값 / 3) 중 하나가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그리고 DP의 전 과정을 끝낸 후, 최소 연산을 구현하는 과정을 모두 출력할 때, procedure[idx]를 출력하고 idx의 값을 procedure[idx]로 갱신하며 procedure[idx]가 1일 때까지 반복한다. 그 후 1을 출력해주면 끝!&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1587190524439&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int dp[1000001];
int procedure[1000001];

int process(int start) {
    if (start == 1) { return 0; }

    auto &amp;amp; ref = dp[start];
    if (ref) return ref;

    ref = process(start - 1) + 1;
    procedure[start] = start - 1;
    if (start % 2 == 0) {
        int temp = process(start / 2) + 1;
        if (ref &amp;gt; temp) {
            ref = temp;
            procedure[start] = start / 2;
        }
    }
    if (start % 3 == 0) {
        int temp = process(start / 3) + 1;
        if (ref &amp;gt; temp) {
            ref = temp;
            procedure[start] = start / 3;
        }
    }
    return ref;
}

int main() {
    int n;
    cin &amp;gt;&amp;gt; n;
    cout &amp;lt;&amp;lt; process(n) &amp;lt;&amp;lt; '\n';
    cout &amp;lt;&amp;lt; n &amp;lt;&amp;lt; ' ';

    int idx = n;
    while (procedure[idx] != 1) {
        cout &amp;lt;&amp;lt; procedure[idx] &amp;lt;&amp;lt; ' ';
        idx = procedure[idx];
    }
    cout &amp;lt;&amp;lt; 1;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>dp</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/83</guid>
      <comments>https://hoondev.tistory.com/83#entry83comment</comments>
      <pubDate>Sat, 18 Apr 2020 15:43:56 +0900</pubDate>
    </item>
    <item>
      <title>4월 18일 공부 계획</title>
      <link>https://hoondev.tistory.com/82</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적 계획법(DP)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 12852&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 7579&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;분할 정복&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1074&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이분 탐색&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 12015&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1806&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/82</guid>
      <comments>https://hoondev.tistory.com/82#entry82comment</comments>
      <pubDate>Sat, 18 Apr 2020 13:51:53 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1520 - 내리막 길 문제풀이</title>
      <link>https://hoondev.tistory.com/81</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으며, 각 지점 사이의 이동은 지도에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;상하좌우&lt;/b&gt; &lt;/span&gt;이웃한 곳끼리만 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;169&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duZ3W7/btqDvxHlpN8/KAuTHrrGNLDtOEVbKZQtkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duZ3W7/btqDvxHlpN8/KAuTHrrGNLDtOEVbKZQtkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duZ3W7/btqDvxHlpN8/KAuTHrrGNLDtOEVbKZQtkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduZ3W7%2FbtqDvxHlpN8%2FKAuTHrrGNLDtOEVbKZQtkK%2Fimg.png&quot; data-origin-width=&quot;169&quot; data-origin-height=&quot;132&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;현재 제일 왼쪽 위 칸이 나타내는 지점에 있는 세준이는 제일 오른쪽 아래 칸이 나타내는 지점으로 가려고 한다. 그런데 가능한 힘을 적게 들이고 싶어 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;항상 높이가 더 낮은 지점으로만 이동&lt;/b&gt;&lt;/span&gt;하여 목표 지점까지 가고자 한다. 위와 같은 지도에서는 다음과 같은 세 가지 경로가 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;172&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btVlPf/btqDvhraEbe/Kgibd5XXdsV2ECQKfgNgV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btVlPf/btqDvhraEbe/Kgibd5XXdsV2ECQKfgNgV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btVlPf/btqDvhraEbe/Kgibd5XXdsV2ECQKfgNgV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtVlPf%2FbtqDvhraEbe%2FKgibd5XXdsV2ECQKfgNgV0%2Fimg.png&quot; data-origin-width=&quot;172&quot; data-origin-height=&quot;294&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNN2Om%2FbtqDx6Bji3Q%2FjReB14xibKkCvhUeoxtJKk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;지도가 주어질 때 이와 같이 제일 왼쪽 위 지점에서 출발하여 제일 오른쪽 아래 지점까지 항상 내리막길로만 이동하는 경로의 개수를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다. M과 N은 각각 500이하의 자연수이고, 각 지점의 높이는 10000이하의 자연수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 이동 가능한 경로의 수 H를 출력한다. 모든 입력에 대하여 H는 10억 이하의 음이 아닌 정수이다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;DFS + DP&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이 문제를 한 마디로 DFS 구현에 DP가 추가된 것이라고 말할 수 있다. 처음 이 문제를 접할 때 DFS로만 접근을 시도했는데, 그 방법으로는 답이 다르게 나왔다.&lt;/p&gt;
&lt;p&gt;그 이유를 문제에 나온 예제 이미지를 보고 파악할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;171&quot; data-origin-height=&quot;161&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mf8PL/btqDxKytQ0Z/oyABHPkrAmFdkPy7yrf3o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mf8PL/btqDxKytQ0Z/oyABHPkrAmFdkPy7yrf3o1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mf8PL/btqDxKytQ0Z/oyABHPkrAmFdkPy7yrf3o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmf8PL%2FbtqDxKytQ0Z%2FoyABHPkrAmFdkPy7yrf3o1%2Fimg.png&quot; data-origin-width=&quot;171&quot; data-origin-height=&quot;161&quot; data-filename=&quot;blob&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNN2Om/btqDx6Bji3Q/jReB14xibKkCvhUeoxtJKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNN2Om%2FbtqDx6Bji3Q%2FjReB14xibKkCvhUeoxtJKk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;첫 번째 사진과 두 번째 사진을 보자면, 17에서 20으로 가는 동선이 겹친다. 만약 첫 번째 사진의 동선을 먼저 DFS가 처리했다면, 두 번째 사진의 동선에서 17 &amp;gt; 15 &amp;gt; 10 으로 가는 동선은 이미 왔던 곳(check[y][x]가 true인 곳)이므로 더 이상 진행하지 않게 된다.&lt;/p&gt;
&lt;p&gt;이 문제를 해결하기 위해 DP를 사용했다. 17이 적혀있는 위치에서 종착점(10)으로 가는 동선은 이미 첫 번째 사진에서 갔다 왔으므로 똑같은 루트를 한 번 더 가는 것은 시간 낭비이다. 따라서 DP(동적 계획법)를 이용해 해당 위치에서 종착점까지 가는 루트의 개수를 저장해놓고 만약 재방문했을 시 O(1)로 값을 리턴하게 한다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;p&gt;// DFS 중심 풀이 (초기점부터 종착점까지 순차적으로 재귀하는 DFS의 원리에 중점)&lt;/p&gt;
&lt;pre id=&quot;code_1587135453034&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

typedef struct {
    int y, x;
} Position;

Position pos[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };

int arr[500][500];
bool check[500][500];
int dp[500][500];
int m, n;

bool isInside(int y, int x) {
    return y &amp;gt;= 0 &amp;amp;&amp;amp; y &amp;lt; m &amp;amp;&amp;amp; x &amp;gt;= 0 &amp;amp;&amp;amp; x &amp;lt; n;
}

int dfs(int y, int x) {
    if (y == m - 1 &amp;amp;&amp;amp; x == n - 1)
        return 1;

    check[y][x] = true;
    auto &amp;amp; ref = dp[y][x];

    for(auto &amp;amp; p : pos) {
        int next_y = y + p.y;
        int next_x = x + p.x;
        if (isInside(next_y, next_x) &amp;amp;&amp;amp; arr[y][x] &amp;gt; arr[next_y][next_x] &amp;amp;&amp;amp; !check[next_y][next_x])
            ref += dfs(next_y, next_x);
        else if (isInside(next_y, next_x) &amp;amp;&amp;amp; arr[y][x] &amp;gt; arr[next_y][next_x] &amp;amp;&amp;amp; check[next_y][next_x])
            ref += dp[next_y][next_x];
    }
    return ref;
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin &amp;gt;&amp;gt; m &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; m; i++) {
        for (int j = 0; j &amp;lt; n; j++) {
            cin &amp;gt;&amp;gt; arr[i][j];
        }
    }
    dfs(0, 0);
    cout &amp;lt;&amp;lt; dp[0][0];
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// DP 중심 풀이 (Top-down 재귀에 중점)&lt;/p&gt;
&lt;pre id=&quot;code_1587135786153&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

typedef struct {
    int y, x;
} Position;

Position pos[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };

int arr[500][500];
bool check[500][500];
int dp[500][500];
int m, n;

bool isInside(int y, int x) {
    return y &amp;gt;= 0 &amp;amp;&amp;amp; y &amp;lt; m &amp;amp;&amp;amp; x &amp;gt;= 0 &amp;amp;&amp;amp; x &amp;lt; n;
}

int dfs(int y, int x) {
    if (y == 0 &amp;amp;&amp;amp; x == 0)
        return 1;

    check[y][x] = true;
    auto &amp;amp; ref = dp[y][x];

    for(auto &amp;amp; p : pos) {
        int next_y = y + p.y;
        int next_x = x + p.x;
        if (isInside(next_y, next_x) &amp;amp;&amp;amp; arr[y][x] &amp;lt; arr[next_y][next_x] &amp;amp;&amp;amp; !check[next_y][next_x])
            ref += dfs(next_y, next_x);
        else if (isInside(next_y, next_x) &amp;amp;&amp;amp; arr[y][x] &amp;lt; arr[next_y][next_x] &amp;amp;&amp;amp; check[next_y][next_x])
            ref += dp[next_y][next_x];
    }
    return ref;
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin &amp;gt;&amp;gt; m &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; m; i++) {
        for (int j = 0; j &amp;lt; n; j++) {
            cin &amp;gt;&amp;gt; arr[i][j];
        }
    }
    dfs(m - 1, n - 1);
    cout &amp;lt;&amp;lt; dp[m - 1][n - 1];
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/81</guid>
      <comments>https://hoondev.tistory.com/81#entry81comment</comments>
      <pubDate>Sat, 18 Apr 2020 00:03:10 +0900</pubDate>
    </item>
    <item>
      <title>4월 17일  공부 계획</title>
      <link>https://hoondev.tistory.com/80</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적 계획법(DP)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;BOJ 1520&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;BOJ 12852&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;기타&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;창설 과제 제출&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/문제풀이</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/80</guid>
      <comments>https://hoondev.tistory.com/80#entry80comment</comments>
      <pubDate>Wed, 15 Apr 2020 15:02:03 +0900</pubDate>
    </item>
    <item>
      <title>4월 14일 알고리즘 공부 계획</title>
      <link>https://hoondev.tistory.com/79</link>
      <description>&lt;h3&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적 계획법(DP)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BOJ 1520&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;분할 정복&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;BOJ 11401&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이분 탐색&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;BOJ 2110&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;큐, 덱&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1021&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 5430&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 2164&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 11866&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;기타&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;s&gt;자료구조 과제 2 제출&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/79</guid>
      <comments>https://hoondev.tistory.com/79#entry79comment</comments>
      <pubDate>Tue, 14 Apr 2020 17:27:25 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 11049 - 행렬 곱셈 순서 문제풀이</title>
      <link>https://hoondev.tistory.com/78</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;크기가 N&amp;times;M인 행렬&amp;nbsp;A와 M&amp;times;K인&amp;nbsp;B를 곱할 때 필요한 곱셈 연산의 수는 총&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; N&amp;times;M&amp;times;K&lt;/b&gt;&lt;/span&gt;번이다. 행렬 N개를 곱하는데 필요한 곱셈 연산의 수는 행렬을 곱하는 순서에 따라 달라지게 된다.&lt;/p&gt;
&lt;p&gt;예를 들어, A의 크기가 5&amp;times;3이고, B의 크기가 3&amp;times;2, C의 크기가 2&amp;times;6인 경우에 행렬의 곱&amp;nbsp;ABC를 구하는 경우를 생각해보자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AB를 먼저 곱하고 C를 곱하는 경우 (AB)C에 필요한 곱셈 연산의 수는 5&amp;times;3&amp;times;2 + 5&amp;times;2&amp;times;6 = 30 + 60 = 90번이다.&lt;/li&gt;
&lt;li&gt;BC를 먼저 곱하고 A를 곱하는 경우 A(BC)에 필요한 곱셈 연산의 수는 3&amp;times;2&amp;times;6 + 5&amp;times;3&amp;times;6 = 36 + 90 = 126번이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;같은 곱셈이지만, 곱셈을 하는 순서에 따라서 곱셈 연산의 수가 달라진다.&lt;/p&gt;
&lt;p&gt;행렬 N개의 크기가 주어졌을 때, 모든 행렬을 곱하는데 필요한 곱셈 연산 횟수의 최솟값을 구하는 프로그램을 작성하시오. 입력으로 주어진 행렬의 순서를 바꾸면 안 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 행렬의 개수 N(1 &amp;le; N &amp;le; 500)이 주어진다.&lt;/p&gt;
&lt;p&gt;둘째 줄부터 N개 줄에는 행렬의 크기 r과 c가 주어진다. (1 &amp;le; r, c &amp;le; 500)&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;항상 순서대로 곱셈을 할 수 있는 크기만 입력으로 주어진다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 입력으로 주어진 행렬을 곱하는데 필요한 곱셈 연산의 최솟값을 출력한다. 정답은 231-1 보다 작거나 같은 자연수이다. 또한, 최악의 순서로 연산해도 연산 횟수가 2^31-1보다 작거나 같다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;DP 문제 중 파일 합치기 문제와 비슷하게 진행되는 문제이다. 이런 유형의 문제가 많이 있는 것 같으니 정확하게 공부해두자!&lt;/p&gt;
&lt;p&gt;처음 N개의 행렬의 세로, 가로 길이를 입력받는다. 입력받은 N개의 행렬 정보는 Matrix 구조체 변수의 arr에 저장된다. 그 후, 우리는 행렬의 곱셈 연산의 수를 계산해야 한다. 우리는 dp라는 이름의 2차원 배열을 선언하여 첫 번째 인덱스부터 두 번째 인덱스까지의 행렬곱을 진행했을 때 그 연산의 수를 저장한다. (dp[i][j])&lt;/p&gt;
&lt;p&gt;i번째 인덱스의 행렬과 j번째 인덱스의 행렬까지의 곱셈 연산의 수의 합은 아래와 같은 점화식으로 나타낼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1586852320004&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// k는 i부터 j - 1까지의 범위를 가진다.
dp[i][j] = min(dp[i][k] + dp[k + 1][j] + arr[i].height * arr[k].width * arr[j].width)&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586851252844&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;climits&amp;gt;
using namespace std;

typedef struct {
    int height, width;
} Matrix;

Matrix arr[500];
int dp[500][500];

int main() {
    int n;
    cin &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; n; i++) {
        cin &amp;gt;&amp;gt; arr[i].height &amp;gt;&amp;gt; arr[i].width;
    }

    for (int i = 1; i &amp;lt; n; i++) {
        for (int j = 0; j + i &amp;lt; n; j++) {
            dp[j][j + i] = INT_MAX;
            for (int k = 0; k &amp;lt;= i - 1; k++) {
                dp[j][j + i] = min(dp[j][j + k] + dp[j + k + 1][j + i]
                        + arr[j].height * arr[j + k].width * arr[j + i].width, dp[j][j + i]);
            }
        }
    }

    cout &amp;lt;&amp;lt; dp[0][n - 1];
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/문제풀이</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/78</guid>
      <comments>https://hoondev.tistory.com/78#entry78comment</comments>
      <pubDate>Tue, 14 Apr 2020 17:23:00 +0900</pubDate>
    </item>
    <item>
      <title>4월 13일 알고리즘 공부 계획</title>
      <link>https://hoondev.tistory.com/77</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;알고리즘&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동적 계획법(DP)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 11049 (내일 정리하기)&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;분할 정복&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1780&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 1629&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이분 탐색&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 2805&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스택&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;BOJ 1874&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 4949&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;BOJ 10773&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;기타&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;s&gt;소프트웨어프로젝트 과제 2 제출&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/77</guid>
      <comments>https://hoondev.tistory.com/77#entry77comment</comments>
      <pubDate>Mon, 13 Apr 2020 01:07:26 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 10816 - 숫자 카드 2 문제풀이</title>
      <link>https://hoondev.tistory.com/76</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 &amp;le; N &amp;le; 500,000)이&amp;nbsp;주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.&lt;/p&gt;
&lt;p&gt;셋째 줄에는 M(1 &amp;le; M &amp;le; 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드가 몇 개인지 출력하는게 문제이다. 이 문제를 처음에는 map을 이용해 문제를 풀었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;map을 이용한 풀이&lt;/h4&gt;
&lt;p&gt;map은 삽입, 삭제, 접근 모두 시간 복잡도가 logn이므로 모든 M개의 수에 대해서 검사하는 시간은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;O(MlogN)&lt;/b&gt;&lt;/span&gt;이다. N이 500000이고, M이 500000이라고 했을 때, 1억보다 작으므로 1초보다 적은 시간이 걸린다고 생각하였다.&lt;/p&gt;
&lt;p&gt;알고리즘은 다음과 같다. 카드에 적혀있는 숫자 int형 key와 그 숫자에 대한 개수를 저장하는 int형 value를 가지는 map&amp;lt;int, int&amp;gt;형 변수를 선언한다. 그리고 처음 N개의 수를 받을 때, map[카드에 적혀있는 숫자]++;를 통해 개수를 증가시킨다.&lt;/p&gt;
&lt;p&gt;그리고 M개의 수를 받을 때, 수를 받을 때마다 map[찾을 숫자]를 통해 개수를 출력하게 하였다. 코드는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1586540882035&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;map&amp;gt;
using namespace std;

map&amp;lt;int, int&amp;gt; cards;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, m;
    cin &amp;gt;&amp;gt; n;
    while (n--) {
        int num;
        cin &amp;gt;&amp;gt; num;
        cards[num]++;
    }
    cin &amp;gt;&amp;gt; m;
    while (m--) {
        int num;
        cin &amp;gt;&amp;gt; num;
        cout &amp;lt;&amp;lt; cards[num] &amp;lt;&amp;lt; ' ';
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그러나, map을 이용한 풀이는 이 문제의 의도가 아니므로 그냥 이런 방법이 있다 정도로만 알고 있자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;upper_bound와 lower_bound를 이용한 풀이&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2020/04/03 - [언어/C, C++] - [C++ STL] upper_bound, lower_bound 알아보기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1586540956532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[C++ STL] upper_bound, lower_bound 알아보기&quot; data-og-description=&quot;lower_bound 개요 특징 이진 탐색(binary_search)의 근간이 된다. algorithm 헤더에 포함되어 있다. 설명 이진 탐색 기반의 탐색이므로, 배열 또는 리스트가 오름차순 정렬되어 있어야 한다. 찾으려고 하는 key 값..&quot; data-og-host=&quot;hoondev.tistory.com&quot; data-og-source-url=&quot;https://hoondev.tistory.com/53&quot; data-og-url=&quot;https://hoondev.tistory.com/53&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/56mND/hyFDru2Irl/50c4NhrEIKH8bA6kMsKuZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/VhUTm/hyFDqiA8pQ/GRxhzzXCgdHUF2xGlx8K1k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hoondev.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hoondev.tistory.com/53&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/56mND/hyFDru2Irl/50c4NhrEIKH8bA6kMsKuZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/VhUTm/hyFDqiA8pQ/GRxhzzXCgdHUF2xGlx8K1k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[C++ STL] upper_bound, lower_bound 알아보기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;lower_bound 개요 특징 이진 탐색(binary_search)의 근간이 된다. algorithm 헤더에 포함되어 있다. 설명 이진 탐색 기반의 탐색이므로, 배열 또는 리스트가 오름차순 정렬되어 있어야 한다. 찾으려고 하는 key 값..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;hoondev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;upper_bound와 lower_bound 모두 logn의 시간 복잡도로 값을 얻을 수 있다. 따라서 총 O(MlogN)의 시간이 걸린다. 처음 N개의 수를 vector를 이용해 저장하고, 그 수를 오름차순으로 정렬한다. 그리고 다음 M개의 수에 대해 아래와 같은 코드를 적용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1586541050434&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cout &amp;lt;&amp;lt; upper_bound(cards.begin(), cards.end(), num) - lower_bound(cards.begin(), cards.end(), num) &amp;lt;&amp;lt; ' ';&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(upper_bound와 lower_bound에 대해 이미 알고 있다는 전제 하에 설명하겠습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;아래 예시를 보자.&lt;/p&gt;
&lt;p&gt;정렬된 N개의 수가 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, 1, &lt;b&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;2&lt;/span&gt;&lt;/b&gt;, 3, 4, 5, 6, 9 일 때, 우리가 1의 개수를 알고 싶다고 하자.&lt;/p&gt;
&lt;p&gt;upper_bound(begin, end, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)를 하면 &lt;span style=&quot;color: #6164c6;&quot;&gt;&lt;b&gt;세 번째 원소를 가리키는 이터레이터&lt;/b&gt;&lt;/span&gt;가 반환된다. 그 이유는 upper_bound는 정렬된 배열에서&lt;b&gt; 찾고자 하는 수보다 큰 수 중에서 처음으로 찾은 수를&lt;/b&gt;&amp;nbsp;가리키는 이터레이터를 반환하는 함수이기 때문이다.&lt;/p&gt;
&lt;p&gt;lower_bound(begin, end, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)를 하면 &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;첫 번째 원소를 가리키는 이터레이터&lt;/span&gt;&lt;/b&gt;가 반환된다. 그 이유는 lower_bound는 정렬된 배열에서 &lt;b&gt;찾고자 하는 수보다 작지 않은 값(이상의 값) 중에서 처음으로 찾은 수를&lt;/b&gt; 가리키는 이터레이터를 반환하는 함수이기 때문이다.&lt;/p&gt;
&lt;p&gt;따라서, (upper_bound 반환 값 - lower_bound 반환 값)을 하면 (3번째를 가리키는 이터레이터 - 1번째를 가리키는 이터레이터)이므로 찾고자 하는 수인 1의 개수를 얻을 수 있다.&lt;/p&gt;
&lt;p&gt;이러한 upper_bound와 lower_bound의 원리를 이용하여 찾고자 하는 수의 개수를 얻을 수 있다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586541463267&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

vector&amp;lt;int&amp;gt; cards;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, m;
    cin &amp;gt;&amp;gt; n;
    while (n--) {
        int num;
        cin &amp;gt;&amp;gt; num;
        cards.push_back(num);
    }
    sort(cards.begin(), cards.end());
    cin &amp;gt;&amp;gt; m;
    while (m--) {
        int num;
        cin &amp;gt;&amp;gt; num;
        cout &amp;lt;&amp;lt; upper_bound(cards.begin(), cards.end(), num) - lower_bound(cards.begin(), cards.end(), num) &amp;lt;&amp;lt; ' ';
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>이분탐색</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/76</guid>
      <comments>https://hoondev.tistory.com/76#entry76comment</comments>
      <pubDate>Sat, 11 Apr 2020 02:58:03 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 2206 - 벽 부수고 이동하기</title>
      <link>https://hoondev.tistory.com/75</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;N&amp;times;M의 행렬로 표현되는 맵이 있다. 맵에서 &lt;b&gt;0은 이동할 수 있는 곳&lt;/b&gt;을 나타내고, &lt;b&gt;1은 이동할 수 없는 벽이 있는 곳&lt;/b&gt;을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;최단 경로&lt;/b&gt;&lt;/span&gt;로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.&lt;/p&gt;
&lt;p&gt;만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;벽을 한 개 까지 부수고 이동하여도 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N(1 &amp;le; N &amp;le; 1,000), M(1 &amp;le; M &amp;le; 1,000)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 최단 거리를 출력한다. 불가능할 때는 &lt;b&gt;-1&lt;/b&gt;을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;우선 지도에서 특정 위치까지 가는 최단 거리를 구하는 문제이므로, BFS를 이용하여 문제를 풀면 된다. 단, 벽을 한 개 까지 부수고 이동하여도 된다는 조건이 있으므로 이 조건에 유의하여 코드를 짜야한다.&lt;/p&gt;
&lt;p&gt;지금까지 BFS를 이용한 최단거리 알고리즘을 풀 때와는 다르게, check 함수를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;3차원&lt;/b&gt;&lt;/span&gt;으로 선언해야 한다. 그 이유는, 벽을 부수고 이동했을 때의 경로와 벽을 부수지 않고 이동했을 때의 경로가 겹칠 경우에 문제가 생기기 때뭉니다.&lt;/p&gt;
&lt;p&gt;예를 들어, 벽을 부수고 이동한 경로에서 (2, 4)라는 특정 위치를 통과했다고 치자. 그러면 그 위치에서 check해주는 방문 배열이 true가 된다. 따라서, 벽을 부수지 않고 이동한 경로에서 (2, 4)를 통과할 때 check가 true이므로, 그 위치를 통과할 수 없게 된다. 비록 그 경로가 '최단 경로'여도..&lt;/p&gt;
&lt;p&gt;따라서 check[세로위치][가로위치]&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[2]&lt;/b&gt;&lt;/span&gt;와 같이 3차원 배열로 선언하여, 그 경로가 이미 벽을 부순 적이 있는 경로라면 check[y][x]&lt;span style=&quot;background-color: #006dd7; color: #ffffff;&quot;&gt;&lt;b&gt;[1]&lt;/b&gt;&lt;/span&gt;에 기록하고, 그렇지 않은 경로라면 check[y][x]&lt;span style=&quot;background-color: #006dd7; color: #ffffff;&quot;&gt;&lt;b&gt;[0]&lt;/b&gt;&lt;/span&gt;에 기록하면 된다.&lt;/p&gt;
&lt;p&gt;정리하면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큐(Queue)에는 Block이라는 구조체 객체가 들어간다.&lt;/li&gt;
&lt;li&gt;Block 구조체는, 현재 위치의
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;위치 정보 (y, x)&lt;/li&gt;
&lt;li&gt;벽을 이미 한 번 부순 적이 있는 경로인지 여부 (isBroken)&lt;/li&gt;
&lt;li&gt;현재 위치까지의 거리 (length)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;현재 위치에서 오른쪽, 왼쪽, 위, 아래 방향으로 1칸 이동한 위치(next_y, next_x)에 대하여
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;맵 내부에 있고 (isInside() 함수를 통해 확인)&lt;/li&gt;
&lt;li&gt;한 번도 방문한 적 없는 곳일 때 (!check[next_y][next_x][now.isBroken]&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;그 방향으로 1칸 이동한 위치가 (next_val) 벽&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/span&gt;이라면 두 가지 선택을 할 수 있다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;벽을 부수고, 그 방향으로 가는 방법. 이때 isBroken을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;true&lt;/b&gt;&lt;/span&gt;로 만든 Block 객체를 큐에 push한다.&lt;/li&gt;
&lt;li&gt;벽을 이미 부순 적이 있다면(now.isBroken == &lt;b&gt;true&lt;/b&gt;), &lt;b&gt;continue;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;그 방향으로 1칸 이동한 위치가 (next_val) 길&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(0)&lt;/b&gt;&lt;/span&gt;이라면
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;now.isBroken의 값은 유지한 채, 다음 위치에서의 정보와 함께 큐에 push한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;check[next_y][next_x][now.isBroken] = true;을 통해 방문 정보를 등록한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586436700538&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
using namespace std;

int n, m;
int arr[1001][1001];
bool check[1001][1001][2];

typedef struct {
    int y, x;
    bool isBroken;
    int length;
} Block;

typedef struct {
    int y, x;
} Direction;

Direction dir[4] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };

bool isInside(int y, int x) {
    return y &amp;gt;= 1 &amp;amp;&amp;amp; x &amp;gt;= 1 &amp;amp;&amp;amp; y &amp;lt;= n &amp;amp;&amp;amp; x &amp;lt;= m;
}

int bfs() {
   queue&amp;lt;Block&amp;gt; q;
   q.push({1, 1, false, 1});
   check[1][1][0] = true;

   while (!q.empty()) {
       auto now = q.front();
       q.pop();

       if (now.y == n &amp;amp;&amp;amp; now.x == m)
           return now.length;

       for (auto &amp;amp; d : dir) {
           int next_y = now.y + d.y;
           int next_x = now.x + d.x;
           auto &amp;amp; next_val = arr[next_y][next_x];
           if (isInside(next_y, next_x) &amp;amp;&amp;amp; !check[next_y][next_x][now.isBroken]) {
               if (next_val) {
                   if (now.isBroken)
                       continue;
                   else {
                       q.push({next_y, next_x, true, now.length + 1});
                   }
               } else
                   q.push({next_y, next_x, now.isBroken, now.length + 1});
               check[next_y][next_x][now.isBroken] = true;
           }
       }
   }
   return -1;
}

int main() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;

    for (int i = 1; i &amp;lt;= n; i++) {
        string temp;
        cin &amp;gt;&amp;gt; temp;
        for (int j = 0; j &amp;lt; temp.length(); j++)
            arr[i][j + 1] = temp[j] - '0';
    }

    cout &amp;lt;&amp;lt; bfs();
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>BFS</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>최단경로</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/75</guid>
      <comments>https://hoondev.tistory.com/75#entry75comment</comments>
      <pubDate>Thu, 9 Apr 2020 22:31:48 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 12865 - 평범한 배낭(냅색 알고리즘) 문제풀이</title>
      <link>https://hoondev.tistory.com/74</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;이 문제는 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&lt;b&gt;아주 평범한 배낭&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;에 관한 문제이다.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다닐 배낭 또한 &lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt;최대한 가치 있게&lt;/b&gt;&lt;/span&gt; 싸려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;준서가 여행에 필요하다고 생각하는 N개의 물건이 있다. 각 물건은 무게 W와 가치 V를 가지는데, 해당 물건을 배낭에 넣어서 가면 준서가 V만큼 즐길 수 있다. 아직 행군을 해본 적이 없는 준서는 최대 K무게까지의 배낭만 들고 다닐 수 있다. 준서가 최대한 즐거운 여행을 하기 위해 배낭에 넣을 수 있는 물건들의 가치의 최댓값을 알려주자.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫 줄에 물품의 수 &lt;b&gt;N(1 &amp;le; N &amp;le; 100)&lt;/b&gt;과 준서가 버틸 수 있는 무게&lt;b&gt; K(1 &amp;le; K &amp;le; 100,000)&lt;/b&gt;가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 &amp;le; W &amp;le; 100,000)와 해당 물건의 가치 V(0 &amp;le; V &amp;le; 1,000)가 주어진다.&lt;/p&gt;
&lt;p&gt;입력으로 주어지는 모든 수는 정수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;한 줄에 배낭에 넣을 수 있는 물건들의 가치합의 최댓값을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;배낭 알고리즘 (Knapsack Algorithm)&lt;/h4&gt;
&lt;p&gt;배낭에 담을 수 있는 무게의 최댓값이 정해져 있고, 일정 가치와 무게가 있는 짐들을 배낭에 넣을 때, 가치의 합이 최대가 되도록 짐을 고르는 방법을 찾는 알고리즘을 뜻합니다.&lt;/p&gt;
&lt;p&gt;이 문제는 대표적인 배낭 알고리즘 문제입니다. 문제에서 주어진 아래 예시를 가지고 설명하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1586412941595&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;4 7
6 13
4 8
3 6
5 12&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;총 물품의 수는 4개, 배낭에 담을 수 있는 무게의 최댓값은 7입니다. 아래는 4개의 물품을 설명의 편의를 위해 오름차순으로 정렬한 것입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;무게 3, 가치 6&lt;/li&gt;
&lt;li&gt;무게 4, 가치 8&lt;/li&gt;
&lt;li&gt;무게 5, 가치 12&lt;/li&gt;
&lt;li&gt;무게 6, 가치 13&lt;/li&gt;
&lt;/ol&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 115px;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;dp&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;j = 0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;6&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;j =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;7&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;i = 0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;i = 1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;i = 2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;i = 3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 19px; text-align: center;&quot;&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;i = 4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;13&lt;/td&gt;
&lt;td style=&quot;width: 10%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;14&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;* dp[i][j]는 j의 무게까지 담을 수 있는 배낭에 1번째부터 i번째 물품을 사용하여 배낭에 담을 수 있는 최대 가치를 뜻한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;* obj[i]는 i번째 물품에 대한 정보를 뜻하고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;obj[i].first는 그 물품의 무게, obj[i].second는 그 물품의 가치&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;를 뜻한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;3가지 예시를 통해 이해해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;i = 2, j = 4 -&amp;gt; dp[2][4]
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;obj[2].second == 8&lt;br /&gt;2번째 물품 하나를 가방에 넣으면 총 가치는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;8&lt;/b&gt;&lt;/span&gt;, 총 무게는 4, 남는 무게는 0이다.&lt;br /&gt;이때, 1부터 1번째 물품을 사용해 남는 무게에 대한 가치 최댓값을 마저 더해주면 된다.&lt;br /&gt;--&amp;gt; obj[2].second + dp[2 - 1][4 - 4&lt;b&gt;(obj[2].first)&lt;/b&gt;] == 8 + 0 == &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;8&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;dp[2 - 1][4] == 6&lt;br /&gt;1번째부터 1번째 물품을 사용하여 총 무게를 4로 맞췄을 때 총 가치는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;8 &amp;gt; 6이므로, dp[2][4] = obj[2].second + dp[1][0] == &lt;span style=&quot;color: #ee2323;&quot;&gt;8&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;i = 2, j = 7 -&amp;gt; dp[2][7]
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;obj[2].second == 8&lt;br /&gt;2번째 물품 하나를 가방에 넣으면 총 가치는 8, 총 무게는 4, 남는 무게는 3이다.&lt;br /&gt;이때, 1부터 1번째 물품을 사용해 남는 무게에 대한 가치 최댓값을 마저 더해주면 된다.&lt;br /&gt;--&amp;gt; obj[2].second + dp[2 - 1][7 - 4&lt;b&gt;(obj[2].first)&lt;/b&gt;] == 8 + 6 == &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;14&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;dp[2 - 1][7] == 6&lt;br /&gt;1번째부터 1번째 물품을 사용하여 총 무게를 7로 맞췄을 때 총 가치는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;14 &amp;gt; 6이므로, dp[2][7] = obj[2].second + dp[1][7] == &lt;span style=&quot;color: #ee2323;&quot;&gt;14&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;단, 위 예시는 obj[i].first(i번째 물품의 무게)가 j 이하라는 것을 가정하였을 때 할 수 있는 이야기이다.&lt;/p&gt;
&lt;p&gt;왜냐하면 j 이상이 아닐 경우, 남는 무게에 대한 dp[i - 1][j - obj[i].first]를 구할 때 j - obj[i].first가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;음수&lt;/b&gt;&lt;/span&gt;가 되버리므로, 메모리 접근 오류가 발생하기 때문이다.&lt;/p&gt;
&lt;p&gt;따라서, &lt;b&gt;obj[i].first가 j 이하일 때만&lt;/b&gt; 위와 같은 매커니즘이 작동하도록 하고 &lt;b&gt;dp[i][j]에 대한 기본값을 dp[i - 1][j]로 초기화&lt;/b&gt; 해놓으면 된다.&lt;/p&gt;
&lt;p&gt;문제의 정답은 i = n, j = k일 때를 구하는 것이므로 답은 &lt;span style=&quot;color: #ffffff; background-color: #006dd7;&quot;&gt;&lt;b&gt;dp[n][k]&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;점화식&lt;/h4&gt;
&lt;pre id=&quot;code_1586415352929&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// dp[i][j]의 초기값
dp[i][j] = dp[i - 1][j]
if (obj[i].first &amp;lt;= j) {
	dp[i][j] = max(obj[i].second + dp[i - 1][j - obj[i].second], dp[i][j])
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586412109730&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

pair&amp;lt;int, int&amp;gt; obj[101];
int arr[101][100001];

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, k;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; k;
    for (int i = 1; i &amp;lt;= n; i++)
        cin &amp;gt;&amp;gt; obj[i].first &amp;gt;&amp;gt; obj[i].second;
    for (int i = 1; i &amp;lt;= n; i++) {
        for (int j = 0; j &amp;lt;= k; j++) {
            arr[i][j] = arr[i - 1][j];
            if (obj[i].first &amp;lt;= j)
                arr[i][j] = max(obj[i].second + arr[i - 1][j - obj[i].first], arr[i][j]);
        }
    }
    cout &amp;lt;&amp;lt; arr[n][k];
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>dp</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/74</guid>
      <comments>https://hoondev.tistory.com/74#entry74comment</comments>
      <pubDate>Thu, 9 Apr 2020 15:56:17 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 10250 - ACM 호텔 문제풀이</title>
      <link>https://hoondev.tistory.com/73</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다.&lt;/p&gt;
&lt;p&gt;문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정하자 (1 &amp;le; H, W &amp;le; 99). 그리고 엘리베이터는 가장 왼쪽에 있다고 가정하자(그림 1 참고). 이런 형태의 호텔을 H &amp;times; W 형태 호텔이라고 부른다. 호텔 정문은 일층 엘리베이터 바로 앞에 있는데, 정문에서 엘리베이터까지의 거리는 무시한다. 또 모든 인접한 두 방 사이의 거리는 같은 거리(거리 1)라고 가정하고&amp;nbsp;호텔의 정면 쪽에만 방이 있다고 가정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnhn8t/btqDfCiaARP/xSWQCQVl4GxLDtXHFJTka0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnhn8t/btqDfCiaARP/xSWQCQVl4GxLDtXHFJTka0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnhn8t/btqDfCiaARP/xSWQCQVl4GxLDtXHFJTka0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcnhn8t%2FbtqDfCiaARP%2FxSWQCQVl4GxLDtXHFJTka0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그림 1. H = 6 이고 W = 12 인 H &amp;times; W 호텔을 간략하게 나타낸 그림&lt;/p&gt;
&lt;p&gt;방 번호는 YXX 나 YYXX 형태인데 여기서 Y 나 YY 는 층 수를 나타내고 XX 는 엘리베이터에서부터 세었을 때의 번호를 나타낸다. 즉, 그림 1 에서 빗금으로 표시한 방은 305 호가 된다.&lt;/p&gt;
&lt;p&gt;손님은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;엘리베이터를 타고 이동하는 거리는 신경 쓰지 않는다.&lt;/b&gt;&lt;/span&gt; 다만 걷는 거리가 같을 때에는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;아래층의 방을 더 선호&lt;/b&gt;&lt;/span&gt;한다. 예를 들면 102 호 방보다는 301 호 방을 더 선호하는데, 102 호는 거리 2 만큼 걸어야 하지만 301 호는 거리 1 만큼만 걸으면 되기 때문이다. 같은 이유로 102 호보다 2101 호를 더 선호한다.&lt;/p&gt;
&lt;p&gt;여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 &amp;le; H, W &amp;le; 99, 1 &amp;le; N &amp;le; H &amp;times; W).&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;N번째 손님이 들어갈 방의 번호는 (방의 층수)(정문으로부터 떨어진 거리)이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;방의 층수 = (N - 1) % (호텔의 높이) + 1&lt;br /&gt;정문으로부터 떨어진 거리 = (N - 1) / (호텔의 높이) + 1&lt;/blockquote&gt;
&lt;p&gt;그런데, 떨어진 거리가 1~9일 경우, 01, 02, 03.. 처럼 숫자 앞에 0이 붙는다. 이를 위해 정문으로부터 떨어진 거리를 출력하기 전에 2개의 cout 속성을 부여한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;cout.width(2); : 2칸의 폭에 맞추어 출력한다.&lt;/li&gt;
&lt;li&gt;cout.fill(0); : 빈 공간은 0으로 채운다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 속성 부여는 속성이 부여된 다음 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;첫 번째 cout 출력에만&lt;/b&gt;&lt;/span&gt; 사용되고 그 이후부터는 속성이 삭제된다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586352432271&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int t;
    cin &amp;gt;&amp;gt; t;
    while (t--) {
        int h, w, n;
        cin &amp;gt;&amp;gt; h &amp;gt;&amp;gt; w &amp;gt;&amp;gt; n;
        cout &amp;lt;&amp;lt; (n - 1) % h + 1;
        cout.width(2);
        cout.fill('0');
        cout &amp;lt;&amp;lt; (n - 1) / h + 1 &amp;lt;&amp;lt; '\n';
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고 문서&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://modoocode.com/152&quot;&gt;https://modoocode.com/152&lt;/a&gt;&lt;/p&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>수학</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/73</guid>
      <comments>https://hoondev.tistory.com/73#entry73comment</comments>
      <pubDate>Wed, 8 Apr 2020 22:53:37 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 2292 - 벌집 문제풀이</title>
      <link>https://hoondev.tistory.com/72</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU3Hn5/btqDiEFAEjD/uLEI9lzBPCEkym3c50ttek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU3Hn5/btqDiEFAEjD/uLEI9lzBPCEkym3c50ttek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU3Hn5/btqDiEFAEjD/uLEI9lzBPCEkym3c50ttek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU3Hn5%2FbtqDiEFAEjD%2FuLEI9lzBPCEkym3c50ttek%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;최소 개수의 방을 지나서 갈 때&lt;/b&gt; &lt;/span&gt;몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N(1 &amp;le; N &amp;le; 1,000,000,000)이 주어진다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;1번부터 시작하여 주어진 번호의 방으로 가는데, 최소 개수의 방을 지나서 가려면 1에서 시작하여&lt;b&gt; 대각선으로 쭉 가는 방법&lt;/b&gt; 밖에 없다. 아래 그림이 그 예시가 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DEMw4/btqDjdOyTDE/yK0N0vRnaIluhmVFIgkVW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DEMw4/btqDjdOyTDE/yK0N0vRnaIluhmVFIgkVW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DEMw4/btqDjdOyTDE/yK0N0vRnaIluhmVFIgkVW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDEMw4%2FbtqDjdOyTDE%2FyK0N0vRnaIluhmVFIgkVW0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 그림과 같이 대각선으로 쭉 가는 거리를 알아내려면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;중심인 1로부터 몇 칸 떨어져 있는지 알아내면 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s6CLq/btqDfCh9vqb/b6cuWpHe4ZpvTMOBSbc8wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s6CLq/btqDfCh9vqb/b6cuWpHe4ZpvTMOBSbc8wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s6CLq/btqDfCh9vqb/b6cuWpHe4ZpvTMOBSbc8wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs6CLq%2FbtqDfCh9vqb%2Fb6cuWpHe4ZpvTMOBSbc8wK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;빨간색 영역에 있는 1이 있는 곳을 중심(=0)이라 한다. 그리고 그 주위를 둘러싸고 있는 방들을 1번째 영역이라고 한다. 또 그 1번째 영역을 둘러싸고 있는 방들을 2번째 영역이라고 한다.&lt;/p&gt;
&lt;p&gt;이렇게 i번째 영역을 둘러싸고 있는 방들의 영역을 i+1번째 영역이라고 하고, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;i번째 영역에 있는 방들은 중심으로부터 i + 1만큼 떨어져 있는 것이 되므로 i + 1가 정답이 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;아래의 표를 보자.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 57px;&quot; border=&quot;1&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;중심(0)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;1번째 영역&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;2번째 영역&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;3번째 영역&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;4번째 영역&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;&lt;b&gt;5번째 영역&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;18&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;24&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;1 + 6 = 7&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;7 + 12 = 19&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;19 + 18 = 37&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;37 + 24 = 61&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center; height: 19px;&quot;&gt;61 + 30 = 91&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;첫 번째 줄은 각 영역에 있는 원소의 개수이고, 두 번째 줄은 중심부터 i번째 영역까지의 원소의 개수 합이다&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;위 표를 통해 13번째 방이 있는 영역을 찾으면 7보다 크고 19보다 작거나 같은 &lt;b&gt;2번째 영역&lt;/b&gt;이므로, 13번째 방은 중심으로부터 1 + 2 = &lt;b&gt;3만큼 떨어져 있으므로&lt;/b&gt; 답이 3이 된다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586349362126&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
    int total = 1;
    int i;
    int n;
    cin &amp;gt;&amp;gt; n;
    for (i = 0; total &amp;lt;= 1000000000; i++) {
        total += i * 6;
        if (total &amp;gt;= n) break;
    }
    cout &amp;lt;&amp;lt; i + 1;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>수학</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/72</guid>
      <comments>https://hoondev.tistory.com/72#entry72comment</comments>
      <pubDate>Wed, 8 Apr 2020 21:40:49 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 3053 - 택시 기하학 문제풀이</title>
      <link>https://hoondev.tistory.com/71</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;19세기 독일 수학자 헤르만 민코프스키는 비유클리드 기하학 중 택시 기하학을 고안했다. 택시 기하학에서 두 점 T1(x1,y1), T2(x2,y2) 사이의 거리는 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;D(T1,T2) = |x1-x2| + |y1-y2|&lt;/blockquote&gt;
&lt;p&gt;두 점 사이의 거리를 제외한 나머지 정의는 유클리드 기하학에서의 정의와 같다. 따라서 택시 기하학에서 원의 정의는 유클리드 기하학에서 원의 정의와 같다.&lt;/p&gt;
&lt;p&gt;원: 평면 상의 어떤 점에서 거리가 일정한 점들의 집합&lt;/p&gt;
&lt;p&gt;반지름 R이 주어졌을 때, 유클리드 기하학에서 원의 넓이와, 택시 기하학에서 원의 넓이를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 반지름 R이 주어진다. R은 10,000보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에는 유클리드 기하학에서 반지름이 R인 원의 넓이를, 둘째 줄에는 택시 기하학에서 반지름이 R인 원의 넓이를 출력한다. 정답과의 오차는&amp;nbsp;0.0001까지 허용한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;유클리드 기하학에서 한 점과 다른 한 점 사이의 거리는 아래와 같이 정의된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;스크린샷 2020-04-08 오후 8.46.24.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPlSao/btqDg5Yh3bG/OtKcmFp4KWpTRIRiDxbjh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPlSao/btqDg5Yh3bG/OtKcmFp4KWpTRIRiDxbjh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPlSao/btqDg5Yh3bG/OtKcmFp4KWpTRIRiDxbjh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPlSao%2FbtqDg5Yh3bG%2FOtKcmFp4KWpTRIRiDxbjh1%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-04-08 오후 8.46.24.png&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;40&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;따라서 원은 아래와 같이 그려진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj1LFt/btqDjdAYRSJ/Rr1YilXCyMBDdOzBOcnl0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj1LFt/btqDjdAYRSJ/Rr1YilXCyMBDdOzBOcnl0k/img.png&quot; data-alt=&quot;유클리드 기하학에서의 원&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj1LFt/btqDjdAYRSJ/Rr1YilXCyMBDdOzBOcnl0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj1LFt%2FbtqDjdAYRSJ%2FRr1YilXCyMBDdOzBOcnl0k%2Fimg.png&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;163&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;유클리드 기하학에서의 원&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;반면에 택시 기하학에서 한 점과 다른 한 점 사이의 거리는 아래와 같이 정의된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;218&quot; data-origin-height=&quot;28&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfRYIZ/btqDiF5A5JH/lQ4R9FFwOZkWxFDgkkweoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfRYIZ/btqDiF5A5JH/lQ4R9FFwOZkWxFDgkkweoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfRYIZ/btqDiF5A5JH/lQ4R9FFwOZkWxFDgkkweoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfRYIZ%2FbtqDiF5A5JH%2FlQ4R9FFwOZkWxFDgkkweoK%2Fimg.png&quot; data-origin-width=&quot;218&quot; data-origin-height=&quot;28&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;따라서 원은 아래와 같이 그려진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-04-08 오후 8.41.26.png&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GOFYW/btqDf2t6IUE/haWEjiBC4tIoS8FJsChkCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GOFYW/btqDf2t6IUE/haWEjiBC4tIoS8FJsChkCK/img.png&quot; data-alt=&quot;택시 기하학에서의 원&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GOFYW/btqDf2t6IUE/haWEjiBC4tIoS8FJsChkCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGOFYW%2FbtqDf2t6IUE%2FhaWEjiBC4tIoS8FJsChkCK%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-04-08 오후 8.41.26.png&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;163&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;택시 기하학에서의 원&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;따라서 유클리드 기하학에서의 원의 넓이는 원래 우리가 알고 있던대로&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;PI(3.1415...) * r^2&lt;/blockquote&gt;
&lt;p&gt;이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;반면에 택시 기하학에서의 원의 넓이는 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;(2 * r) * (2 * r) / 2&lt;/blockquote&gt;
&lt;p&gt;위 공식은 (한 대각선) * (다른 대각선) / 2로, 마름모 넓이 공식이다. 더 나아가, 택시 기하학에서의 원은 항상 정사각형 꼴을 띄므로 정사각형 넓이 공식을 통해 아래와 같이 구할 수도 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;((루트 2) * r)^2&lt;/blockquote&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586345955678&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define _USE_MATH_DEFINES
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cmath&amp;gt;
using namespace std;

int main() {
    int r;
    cin &amp;gt;&amp;gt; r;
    cout &amp;lt;&amp;lt; fixed;
    cout.precision(6);
    cout &amp;lt;&amp;lt; M_PI * pow(r, 2) &amp;lt;&amp;lt; '\n';
    cout &amp;lt;&amp;lt; pow(2 * r, 2) / 2;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;파이 값은 cmath 헤더에 포함된 M_PI 매크로를 사용하면 된다.&lt;/li&gt;
&lt;li&gt;단, M_PI 매크로를 사용하려면, 최상단에 #define _USE_MATH_DEFINES를 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그림 출처&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://m.blog.naver.com/alwaysneoi/100172516753?view=img_7&quot;&gt;https://m.blog.naver.com/alwaysneoi/100172516753?view=img_7&lt;/a&gt;&lt;/p&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>수학</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/71</guid>
      <comments>https://hoondev.tistory.com/71#entry71comment</comments>
      <pubDate>Wed, 8 Apr 2020 20:54:33 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 2580 - 스도쿠 문제풀이</title>
      <link>https://hoondev.tistory.com/70</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루어진 정사각형 판 위에서 이뤄지는데, 게임 시작 전 몇 몇 칸에는 1부터 9까지의 숫자 중 하나가 쓰여 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwDqTp/btqDecRkYQ5/aEDfnJdwWOnivw4GhBDWpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwDqTp/btqDecRkYQ5/aEDfnJdwWOnivw4GhBDWpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwDqTp/btqDecRkYQ5/aEDfnJdwWOnivw4GhBDWpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwDqTp%2FbtqDecRkYQ5%2FaEDfnJdwWOnivw4GhBDWpk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;나머지 빈 칸을 채우는 방식은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;각각의 가로줄과 세로줄에는 1부터 9까지의 숫자가 한 번씩만 나타나야 한다.&lt;/li&gt;
&lt;li&gt;굵은 선으로 구분되어 있는 3x3 정사각형 안에도 1부터 9까지의 숫자가 한 번씩만 나타나야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위의 예의 경우, 첫째 줄에는 1을 제외한 나머지 2부터 9까지의 숫자들이 이미 나타나 있으므로 첫째 줄 빈칸에는 1이 들어가야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZDhxN/btqDeUCJKTz/Ye80VuRWk0AMGax8QMzeTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZDhxN/btqDeUCJKTz/Ye80VuRWk0AMGax8QMzeTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZDhxN/btqDeUCJKTz/Ye80VuRWk0AMGax8QMzeTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZDhxN%2FbtqDeUCJKTz%2FYe80VuRWk0AMGax8QMzeTK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;또한 위쪽 가운데 위치한 3x3 정사각형의 경우에는 3을 제외한 나머지 숫자들이 이미 쓰여있으므로 가운데 빈 칸에는 3이 들어가야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AmjnW/btqDeUipsy4/XsJbiuzfm2RUrB7f6xBYXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AmjnW/btqDeUipsy4/XsJbiuzfm2RUrB7f6xBYXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AmjnW/btqDeUipsy4/XsJbiuzfm2RUrB7f6xBYXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAmjnW%2FbtqDeUipsy4%2FXsJbiuzfm2RUrB7f6xBYXK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이와 같이 빈 칸을 차례로 채워 가면 다음과 같은 최종 결과를 얻을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCc7C/btqDf2fTW74/th45j5yd6TekilNXQw1HT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCc7C/btqDf2fTW74/th45j5yd6TekilNXQw1HT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCc7C/btqDf2fTW74/th45j5yd6TekilNXQw1HT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCc7C%2FbtqDf2fTW74%2Fth45j5yd6TekilNXQw1HT1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;게임 시작 전 스도쿠 판에 쓰여 있는 숫자들의 정보가 주어질 때 모든 빈칸이 채워진 최종 모습을 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;아홉 줄에 걸쳐 한 줄에 9개씩 게임 시작 전 스도쿠판 각 줄에 쓰여 있는 숫자가 한 칸씩 띄워서 차례로 주어진다. 스도쿠 판의 빈칸의 경우에는 0이 주어진다. 스도쿠 판을 규칙대로 채울 수 없는 경우의 입력은 주어지지 않는다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;모든 빈 칸이 채워진 스도쿠 판의 최종 모습을 아홉 줄에 걸쳐 한 줄에 9개씩 한 칸씩 띄워서 출력한다.&lt;/p&gt;
&lt;p&gt;스도쿠 판을 채우는 방법이 여럿인 경우는 그 중 하나만을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-04-08 오전 3.15.36.png&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EPhfa/btqDiELHcsW/DznriP7SA1uLrALDpp8I0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EPhfa/btqDiELHcsW/DznriP7SA1uLrALDpp8I0k/img.png&quot; data-alt=&quot;8번 시도의 대장정 끝에... 처음 접근을 잘못하면 이 꼴 납니다...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EPhfa/btqDiELHcsW/DznriP7SA1uLrALDpp8I0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEPhfa%2FbtqDiELHcsW%2FDznriP7SA1uLrALDpp8I0k%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-04-08 오전 3.15.36.png&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;324&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;8번 시도의 대장정 끝에... 처음 접근을 잘못하면 이 꼴 납니다...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 문제는 DFS를 이용한 '백트래킹' 기술로 풀 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;main에서 스도쿠 배열과 스도쿠 배열에서 비어있는 곳의 위치(0)를 &lt;b&gt;v라는 이름의 벡터&lt;/b&gt;에 pair 형태로 저장한다.&lt;/li&gt;
&lt;li&gt;v[i]의 위치에 1부터 9까지의 수를 넣었을 때 스도쿠 조건에 만족하는지 검사한다. (check 함수)&lt;/li&gt;
&lt;li&gt;check가 통과되었을 경우, 해당 위치의 스도쿠 배열에 그 수를 넣고, v[i + 1]에 대해 이 과정을 반복한다.&lt;/li&gt;
&lt;li&gt;그 과정이 성공하였을 경우 true를 리턴하고, 그러지 않았을 경우 v[i]의 위치를 다시&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; '비어있는 상태'&lt;/b&gt;&lt;/span&gt;로 만든 후 다음 수에 대해 스도쿠 조건에 만족하는지 검사한다.&lt;/li&gt;
&lt;li&gt;이 과정을 반복하다가, v의 끝까지 검사했을 경우 true를 리턴한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586283283644&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;

int arr[9][9];
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; v;

bool check(int y, int x, int i) {
    for (int k = 0; k &amp;lt; 9; k++) {
        if (arr[y][k] == i || arr[k][x] == i)
            return false;
    }
    for (int k = (y / 3) * 3; k &amp;lt; (y / 3) * 3 + 3; k++) {
        for (int j = (x / 3) * 3; j &amp;lt; (x / 3) * 3 + 3; j++) {
            if (arr[k][j] == i)
                return false;
        }
    }
    return true;
}

bool dfs(int cur) {
    if (cur == v.size()) return true;
    int y = v[cur].first;
    int x = v[cur].second;
    for (int i = 1; i &amp;lt;= 9; i++) {
        if (check(y, x, i)) {
            arr[y][x] = i;
            if (dfs(cur + 1)) return true;
            arr[y][x] = 0;
        }
    }
    return false;
}

int main() {
    for (auto &amp;amp; i : arr) for (int &amp;amp; j : i) cin &amp;gt;&amp;gt; j;
    for (int i = 0; i &amp;lt; 9; i++) {
        for (int j = 0; j &amp;lt; 9; j++) {
            if (arr[i][j] == 0)
                v.push_back({i, j});
        }
    }
    dfs(0);
    for (auto &amp;amp; i : arr) {
        for (int &amp;amp; j : i) cout &amp;lt;&amp;lt; j &amp;lt;&amp;lt; ' ';
        cout &amp;lt;&amp;lt; '\n';
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>백트래킹</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/70</guid>
      <comments>https://hoondev.tistory.com/70#entry70comment</comments>
      <pubDate>Wed, 8 Apr 2020 03:29:31 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1654 - 랜선 자르기 문제풀이</title>
      <link>https://hoondev.tistory.com/69</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이&amp;nbsp;캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.&lt;/p&gt;
&lt;p&gt;이미 오영식은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm 은 &lt;b&gt;버려야 한다.&lt;/b&gt; (이미 자른 랜선은 붙일 수 없다.)&lt;/p&gt;
&lt;p&gt;편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다.&lt;/b&gt;&lt;/span&gt; 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. &lt;b&gt;K는 1이상 &lt;span style=&quot;color: #006dd7;&quot;&gt;10,000이하&lt;/span&gt;의 정수&lt;/b&gt;이고, &lt;b&gt;N은 1이상 &lt;span style=&quot;color: #006dd7;&quot;&gt;1,000,000이하&lt;/span&gt;의 정수&lt;/b&gt;이다. 그리고 항상 K ≦ N 이다. 그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;2&lt;sup&gt;31&lt;/sup&gt;-1보다&amp;nbsp;작거나&amp;nbsp;같은&amp;nbsp;자연수&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;이 문제를 완전 탐색으로 접근한다면, O(최대 랜선의 길이) * O(K)로 최대 21억 * 10000, 약 210000초가 걸릴 것이다. 따라서 우리는 선형 연산이 아닌, 로그형 연산을 시행해야 한다. 로그형 연산으로 탐색을 수행할 수 있는 알고리즘은 이분 탐색(Binary Search)이 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;(front) &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; ~ (back) &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;오영식이 가지고 있는 K개의 랜선 중 가장 긴 랜선의 길이&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;위 범위를 시작으로, 이분 탐색을 시행한다. 아래는 이분 탐색 원리를 안다는 가정 하에 설명한 내용이다.&lt;/p&gt;
&lt;p&gt;mid값을 front와 back의 평균값보다 큰 수 중 최소 정수이라고 하자. (401.2 -&amp;gt; 402)&lt;/p&gt;
&lt;p&gt;mid 값으로 &lt;u&gt;K개의 랜선을 나눈 값 각각&lt;/u&gt;은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;mid의 길이로 만들 수 있는 랜선의 개수를 의미&lt;/b&gt;&lt;/span&gt;하고, 그 각각의 총합은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;K개의 랜선을 mid의 길이로 만들 수 있는 랜선의 개수 총합&lt;span style=&quot;color: #ee2323;&quot;&gt;(sum)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;sum&lt;/span&gt;&lt;/b&gt;이 N보다 작으면 mid보다 더 짧은 길이로 만들어야 한다는 것을 의미하므로, back을 mid - 1로 만든다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;sum&lt;/b&gt;&lt;/span&gt;이 N보다 크거나 같으면 mid보다 길거나 같은 길이로 만들어야 한다는 것을 의미하므로, front를 mid로 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 과정을 front와 back이 &lt;b&gt;같아질 때까지&lt;/b&gt; 시행하면 된다. 이 때의 front 또는 back값이 N개 이상을 만들 수 있는 랜선의 최대 길이이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;예시&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예제 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586260188913&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;4&amp;nbsp;8
10
21
17
15&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;진행 과정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;front == 1, back == 21, mid == 11, sum == 0 + 1 + 1 + 1 == 3, sum &amp;lt; n == 8&lt;/li&gt;
&lt;li&gt;front == 1, back == 10, mid == 6, sum == 1 + 3 + 2 + 2 == 9, sum &amp;gt;= n == 8&lt;/li&gt;
&lt;li&gt;front == 6, back == 10, mid == 8, sum == 1 + 2 + 2 + 1 == 6, sum &amp;lt; n == 8&lt;/li&gt;
&lt;li&gt;front == 6, back == 7, mid == 7, sum == 1 + 3 + 2 + 2 == 8, sum &amp;gt;= n == 8&lt;/li&gt;
&lt;li&gt;front == 7, back == 7 --&amp;gt; 종료&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586259129232&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cmath&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;

vector&amp;lt;int&amp;gt; lan;

int main() {
    cout.tie(NULL);
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    int k, n;
    cin &amp;gt;&amp;gt; k &amp;gt;&amp;gt; n;

    for (int i = 0; i &amp;lt; k; i++) {
        int temp;
        cin &amp;gt;&amp;gt; temp;
        lan.push_back(temp);
    }

    long long back = (*max_element(lan.begin(), lan.end()));
    long long front = 1;
    while (front != back) {
        long long sum = 0;
        int mid = ceil((double)(front + back) / 2);
        for (auto &amp;amp; target : lan)
            sum += target / mid;
        if (sum &amp;lt; n)
            back = mid - 1;
        else if (sum &amp;gt;= n)
            front = mid;
    }
    cout &amp;lt;&amp;lt; front;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>이분탐색</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/69</guid>
      <comments>https://hoondev.tistory.com/69#entry69comment</comments>
      <pubDate>Tue, 7 Apr 2020 20:48:36 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1436 - 영화감독 숌</title>
      <link>https://hoondev.tistory.com/68</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워즈를 만들 때, 스타워즈 1, 스타워즈 2, 스타워즈 3, 스타워즈 4, 스타워즈 5, 스타워즈 6과 같이 이름을 지었고, 피터 잭슨은 반지의 제왕을 만들 때, 반지의 제왕 1, 반지의 제왕 2, 반지의 제왕 3과 같이 영화 제목을 지었다.&lt;/p&gt;
&lt;p&gt;하지만 숌은 자신이 조지 루카스와 피터 잭슨을 뛰어넘는다는 것을 보여주기 위해서 영화 제목을 좀 다르게 만들기로 했다.&lt;/p&gt;
&lt;p&gt;종말의 숫자란 어떤 수에 6이 적어도 3개이상 연속으로 들어가는 수를 말한다. 제일 작은 종말의 숫자는 666이고, 그 다음으로 큰 수는 1666, 2666, 3666, .... 과 같다.&lt;/p&gt;
&lt;p&gt;따라서, 숌은 첫 번째 영화의 제목은 세상의 종말 666, 두 번째 영화의 제목은 세상의 종말 1666 이렇게 이름을 지을 것이다. 일반화해서 생각하면, N번째 영화의 제목은 세상의 종말 (N번째로 작은 종말의 숫자) 와 같다.&lt;/p&gt;
&lt;p&gt;숌이 만든 N번째 영화의 제목에 들어간 숫자를 출력하는 프로그램을 작성하시오. 숌은 이 시리즈를 항상 차례대로 만들고, 다른 영화는 만들지 않는다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 숫자 N이 주어진다. N은 10,000보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N번째 영화의 제목에 들어간 수를 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;숫자에 6이 3개 연속된 666이라는 수가 포함되어 있으면 된다. 처음에는 수를 문자열 처리해서 Substring이 &quot;666&quot;을 찾는 것으로 하려고 했으나, 더 간단한 방법이 있음을 알게 되었다.&lt;/p&gt;
&lt;p&gt;우선 1부터 계속 증가하면서 666이 포함된 수를 N개 찾을 때 까지 탐색시켜야 한다. 이때, 현재의 수에 666이 포함되어 있는지 여부를 알기 위해서 아래와 같은 알고리즘을 적용했다.&lt;/p&gt;
&lt;pre id=&quot;code_1586197485956&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (temp) {
	if (temp % 1000 == 666) {
		i++; break;
    }
	temp /= 10;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num : 현재 수를 담아두는 변수&lt;/li&gt;
&lt;li&gt;temp : 현재 수를 복사한 변수 (실제 수를 수정하면 안되므로)&lt;/li&gt;
&lt;li&gt;while (temp) : temp가 0이 아닐 때까지&lt;/li&gt;
&lt;li&gt;if (temp % 1000 == 6666) { i++; break; } : temp % 1000가 666이면 i(찾은 666이 포함된 수)를 1 증가시키고 이 반복문 탈출&lt;/li&gt;
&lt;li&gt;temp /= 10 : temp % 1000이 6666이 아닐 경우 10을 나눈다. 또 다시 temp을 10으로 나눈 값에 대해 검사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;알고리즘 작동 예시&lt;/h4&gt;
&lt;p&gt;(temp는 66611이라고 가정)&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;temp == 166611, temp % 1000 == 611 != 666 이므로 temp /= 10 처리&lt;/li&gt;
&lt;li&gt;temp == 16661, temp % 1000 == 661 != 666 이므로 temp /= 10 처리&lt;/li&gt;
&lt;li&gt;temp == 1666, temp % 1000 == 666 == 666 이므로 i++하고 반복문 탈출&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586197884044&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cmath&amp;gt;
using namespace std;

int i, num;

int main() {
    int n;
    cin &amp;gt;&amp;gt; n;
    while (1) {
        int temp = num;
        while (temp) {
            if (temp % 1000 == 666) {i++; break;}
            temp /= 10;
        }
        if(i == n) break;
        num++;
    }
    cout &amp;lt;&amp;lt; num;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>완전탐색</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/68</guid>
      <comments>https://hoondev.tistory.com/68#entry68comment</comments>
      <pubDate>Tue, 7 Apr 2020 03:29:30 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 1541 - 잃어버린 괄호 문제풀이</title>
      <link>https://hoondev.tistory.com/67</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;세준이는 양수와 +, -, 그리고 괄호를 가지고 길이가 &lt;b&gt;최대 50&lt;/b&gt;인 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.&lt;/p&gt;
&lt;p&gt;그리고 나서 세준이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;괄호를 적절히 쳐서 이 식의 값을 최소로&lt;/b&gt; &lt;/span&gt;만들려고 한다.&lt;/p&gt;
&lt;p&gt;괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 식이 주어진다. 식은 &amp;lsquo;0&amp;rsquo;~&amp;lsquo;9&amp;rsquo;, &amp;lsquo;+&amp;rsquo;, 그리고 &amp;lsquo;-&amp;rsquo;만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이&amp;nbsp;연속되는 숫자는 없다. 수는 0으로 시작할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 정답을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;주어진 식에 괄호를 적절히 쳐서 최솟값을 만들기 위해서는 빼는 수가 최대가 되게 만들면 된다.&lt;/p&gt;
&lt;p&gt;따라서, -가 나오기 전까지 모두 더했다가, -가 나오면 다음 -가 나오기 전까지 - 이후의 수의 합을 구한다. 그리고 그 수를 총합에서 뺀다. 다음 -가 나오면 이 과정을 반복하고, 만약 다음 -가 나오지 않으면, 수식의 끝까지 간 경우이므로 함수를 종료한다.&lt;/p&gt;
&lt;p&gt;필자는 이 기능을 구현하기 전에, string으로 읽어들인 문자열을 Tokenize 하는 작업을 거쳤다. int형 vector에 숫자는 숫자로, 부호는 -면 -1, +면 -2로 저장해놓았다.&lt;/p&gt;
&lt;p&gt;그리고, 토큰화된 정수와 부호(-1, -2로 표현됨)를 읽고 최솟값을 만들어내는 함수를 만들었다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586190624551&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;

vector&amp;lt;int&amp;gt; tokens;

void tokenize(string target) {
    auto it = target.begin();
    while (it != target.end()) {
        if (*it == '-') {
            tokens.push_back(-1);
            it++;
        } else if (*it == '+') {
            tokens.push_back(-2);
            it++;
        } else {
            auto begin = it;
            for (; *it &amp;gt;= '0' &amp;amp;&amp;amp; *it &amp;lt;= '9'; it++) {}
            tokens.push_back(stoi(string(begin, it)));
        }
    }
}

int minimized_value() {
    int total = *tokens.begin();

    auto it = tokens.begin() + 1;
    while (it != tokens.end()) {
        if (*it == -1) {
            it++;
            int temp = 0;
            for (;*it != -1 &amp;amp;&amp;amp; it != tokens.end(); it++) {
                if (*it != -2) {
                    temp += *it;
                }
            }
            total -= temp;
        } else if (*it == -2) {
            total += *(++it);
            it++;
        } else {
            total += *it;
            it++;
        }
    }
    return total;
}

int main() {
    string input;
    cin &amp;gt;&amp;gt; input;
    tokenize(input);
    cout &amp;lt;&amp;lt; minimized_value();
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>그리디</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/67</guid>
      <comments>https://hoondev.tistory.com/67#entry67comment</comments>
      <pubDate>Tue, 7 Apr 2020 01:38:11 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 11399 - ATM 문제풀이</title>
      <link>https://hoondev.tistory.com/66</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;인하은행에는 ATM이 1대밖에 없다. 지금 이 ATM앞에 N명의 사람들이 줄을 서있다. 사람은 1번부터 N번까지 번호가 매겨져 있으며, i번&amp;nbsp;사람이 돈을 인출하는데 걸리는 시간은 Pi분이다.&lt;/p&gt;
&lt;p&gt;사람들이 줄을 서는 순서에 따라서, 돈을 인출하는데 필요한 시간의 합이 달라지게 된다. 예를 들어, 총 5명이 있고, P1&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 3, P2&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 1, P3&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 4, P4&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 3, P5&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 2 인 경우를 생각해보자. [1, 2, 3, 4, 5] 순서로 줄을 선다면, 1번 사람은 3분만에 돈을 뽑을 수 있다. 2번 사람은 1번 사람이 돈을 뽑을 때 까지 기다려야 하기 때문에, 3+1 = 4분이 걸리게 된다. 3번 사람은 1번, 2번 사람이 돈을 뽑을 때까지 기다려야 하기 때문에, 총 3+1+4 = 8분이 필요하게 된다. 4번 사람은 3+1+4+3 = 11분, 5번 사람은 3+1+4+3+2 = 13분이 걸리게 된다. 이 경우에 각 사람이 돈을 인출하는데 필요한 시간의 합은 3+4+8+11+13 = 39분이 된다.&lt;/p&gt;
&lt;p&gt;줄을 [2, 5, 1, 4, 3] 순서로 줄을 서면, 2번 사람은 1분만에, 5번 사람은 1+2 = 3분, 1번 사람은 1+2+3 = 6분, 4번 사람은 1+2+3+3 = 9분, 3번 사람은 1+2+3+3+4 = 13분이 걸리게 된다. 각 사람이 돈을 인출하는데 필요한 시간의 합은 1+3+6+9+13 = 32분이다. 이 방법보다 더 필요한 시간의 합을 최소로 만들 수는 없다.&lt;/p&gt;
&lt;p&gt;줄을 서 있는 사람의 수 N과 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어졌을 때, 각 사람이 돈을 인출하는데 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;필요한 시간의 합의 최솟값&lt;/b&gt;&lt;/span&gt;을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 사람의 수 N(1 &amp;le; N &amp;le; 1,000)이 주어진다. 둘째 줄에는 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어진다. (1 &amp;le; Pi&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 1,000)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에&amp;nbsp;각 사람이 돈을 인출하는데 필요한 시간의 합의 &lt;b&gt;최솟값&lt;/b&gt;을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;처음 이 문제를 DFS로 접근하려고 했으나, 문제를 제대로 다시 읽어보니 각 사람이 돈을 인출하는 시간을 오름차순으로 정렬하면 그 순서가 바로 필요한 시간의 합의 최솟값을 구하는 것이다.&lt;/p&gt;
&lt;p&gt;왜냐하면 오름차순으로 정렬할 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;본인 순서의 앞에 있는 사람들은 항상 최소 시간이 걸리기 때문&lt;/b&gt;&lt;/span&gt;이다. &lt;b&gt;(오름차순의 특징)&lt;/b&gt;&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586084993770&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int main() {
    int n;
    int arr[1000];
    int result = 0;
    cin &amp;gt;&amp;gt; n;

    for (int i = 0; i &amp;lt; n; i++) {
        cin &amp;gt;&amp;gt; arr[i];
    }

    sort(arr, arr + n);

    for (int i = 0; i &amp;lt; n; i++) {
        for (int k = 0; k &amp;lt;= i; k++) {
            result += arr[k];
        }
    }
    cout &amp;lt;&amp;lt; result;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>그리디</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/66</guid>
      <comments>https://hoondev.tistory.com/66#entry66comment</comments>
      <pubDate>Sun, 5 Apr 2020 20:12:26 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 11047 - 동전 0 문제풀이</title>
      <link>https://hoondev.tistory.com/65</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다. 동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;최솟값&lt;/b&gt;&lt;/span&gt;을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 N과 K가 주어진다. (1 &amp;le; N &amp;le; 10, 1 &amp;le; K &amp;le; 100,000,000) 그리고 둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 &amp;le; Ai&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 1,000,000, A1&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 1, i&amp;nbsp;&amp;ge; 2인 경우에&amp;nbsp;Ai는 Ai-1의 배수)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;첫째 줄에 K원을 만드는데 필요한 동전 개수의 최솟값을 출력한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2020/03/27 - [알고리즘/문제풀이] - BOJ 2293 - 동전 1 문제풀이&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1586082811712&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;BOJ 2293 - 동전 1 문제풀이&quot; data-og-description=&quot;문제를 읽고 이해하기 n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 각각의 동전은 몇 개라..&quot; data-og-host=&quot;hoondev.tistory.com&quot; data-og-source-url=&quot;https://hoondev.tistory.com/21&quot; data-og-url=&quot;https://hoondev.tistory.com/21&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/2npmx/hyFys2zYbQ/CB0XLz1y4oMVnfPGSY1uy1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/NpwmG/hyFykwGx9a/mlUXZLosQUUTrF5CMFi7Yk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hoondev.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hoondev.tistory.com/21&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/2npmx/hyFys2zYbQ/CB0XLz1y4oMVnfPGSY1uy1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/NpwmG/hyFykwGx9a/mlUXZLosQUUTrF5CMFi7Yk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;BOJ 2293 - 동전 1 문제풀이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문제를 읽고 이해하기 n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 각각의 동전은 몇 개라..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;hoondev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;이전에 풀이했던 동전 1 문제를 생각해보자. 동전 1 문제는 주어진 동전을 사용하여 K원을 만들 수 있는 모든 경우의 수를 구하는 문제고, 이 문제는 주어진 동전을 이용하여 K원을 만들 수 있는 경우 중 최소한의 동전을 사용하는 경우에서 사용한 동전의 개수를 구하는 문제이다.&lt;/p&gt;
&lt;p&gt;비슷해 보이지만, 근본부터 다른 문제이다. 이 문제는 최솟값이라는 점이 포인트이다. 가장 적은 수의 동전을 사용하려면 주어진 K원보다 작거나 같은 값을 가지는 동전 중에서&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 가장 큰 값을 가지는 동전부터 차례대로 사용&lt;/b&gt;&lt;/span&gt;하는 것이다. 따라서 이 문제는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;그리디&lt;/b&gt;&lt;/span&gt;(탐욕법) 알고리즘을 사용한 문제이다.&lt;/p&gt;
&lt;p&gt;문제 이해만 하면 코딩은 간단하다. 필자는 우선순위 큐(priority_queue)를 이용하여 큰 값을 가지는 동전부터 사용하도록 구현하였다.&lt;span style=&quot;color: #dddddd;&quot;&gt; (생각해보니 입력이 오름차순으로 주어지니 그냥 배열로 선언해도 될 것 같..네요)&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586082274040&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
using namespace std;

priority_queue&amp;lt;int&amp;gt; pq;

int main() {
    int count = 0;
    int n, k;
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; k;

    for (int i = 0; i &amp;lt; n; i++) {
        int temp;
        cin &amp;gt;&amp;gt; temp;
        if (temp &amp;lt;= k)
            pq.push(temp);
    }

    while (k != 0) {
        int now_coin = pq.top();
        if (now_coin &amp;gt; k) {
            pq.pop();
            continue;
        }
        k -= now_coin;
        count++;
    }
    cout &amp;lt;&amp;lt; count;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>그리디</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/65</guid>
      <comments>https://hoondev.tistory.com/65#entry65comment</comments>
      <pubDate>Sun, 5 Apr 2020 19:37:45 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 7569 - 토마토 문제풀이</title>
      <link>https://hoondev.tistory.com/64</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이 격자모양 상자의 칸에 하나씩 넣은 다음, 상자들을 &lt;b&gt;수직으로 쌓아 올려서&lt;/b&gt; 창고에 보관한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkBZsF/btqDdHoPd9z/oykjlM4gtZcMbzJ3kQOGy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkBZsF/btqDdHoPd9z/oykjlM4gtZcMbzJ3kQOGy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkBZsF/btqDdHoPd9z/oykjlM4gtZcMbzJ3kQOGy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkBZsF%2FbtqDdHoPd9z%2FoykjlM4gtZcMbzJ3kQOGy1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토에 인접한 곳은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위, 아래, 왼쪽, 오른쪽, 앞, 뒤 여섯 방향&lt;/b&gt;&lt;/span&gt;에 있는 토마토를 의미한다.&lt;b&gt; 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며&lt;/b&gt;, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지 그 최소 일수를 알고 싶어 한다.&lt;/p&gt;
&lt;p&gt;토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라. 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, &lt;b&gt;2 &amp;le; M &amp;le; 100, 2 &amp;le; N &amp;le; 100, 1 &amp;le; H &amp;le; 100&lt;/b&gt; 이다. 둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 하나의 상자에 담긴 토마토의 정보가 주어진다. 각 줄에는 상자 가로줄에 들어있는 토마토들의 상태가 M개의 정수로 주어진다.&lt;b&gt; 정수 1은 익은 토마토, 정수 0 은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다. 이러한 N개의 줄이 H번 반복하여 주어진다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;여러분은 토마토가 모두 익을 때까지 최소 며칠이 걸리는지를 계산해서 출력해야 한다. 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, 토마토가 모두 익지는 못하는 상황이면 -1을 출력해야 한다.&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hoondev.tistory.com/63&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&amp;gt; BOJ 7576 - 토마토 문제풀이&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;BOJ 7576 - 토마토 문제에서 토마토를 담는 박스가 3차원으로 바뀐 것 뿐이다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586081180371&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;utility&amp;gt;
#include &amp;lt;tuple&amp;gt;
using namespace std;

// m은 가로 칸의 수, n은 세로 칸의 수
int m, n, h;
int arr[101][101][101];
vector&amp;lt;tuple&amp;lt;int, int, int&amp;gt;&amp;gt; tomatoes_pos;
bool check[101][101][101];
int day = 0;

typedef struct {
    int z, y, x;
} Position;

Position pos[6] = {
        { -1, 0, 0 }  , { 1, 0, 0 },
        { 0, -1, 0 }, { 0, 0, -1 }, { 0, 1, 0 }, { 0, 0 , 1 }
};

bool isInside(int z, int y, int x) {
    return z &amp;gt;= 0 &amp;amp;&amp;amp; y &amp;gt;= 0 &amp;amp;&amp;amp; x &amp;gt;= 0 &amp;amp;&amp;amp; z &amp;lt; h &amp;amp;&amp;amp; y &amp;lt; n &amp;amp;&amp;amp; x &amp;lt; m;
}

void bfs() {
    queue&amp;lt;pair&amp;lt;tuple&amp;lt;int, int, int&amp;gt;, int&amp;gt;&amp;gt; q;
    for (auto &amp;amp; tp : tomatoes_pos) {
        q.push({tp, 0});
        check[get&amp;lt;0&amp;gt;(tp)][get&amp;lt;1&amp;gt;(tp)][get&amp;lt;2&amp;gt;(tp)] = true;
    }

    while (!q.empty()) {
        auto now = q.front();
        q.pop();

        for (auto &amp;amp; p : pos) {
            int next_z = get&amp;lt;0&amp;gt;(now.first) + p.z;
            int next_y = get&amp;lt;1&amp;gt;(now.first) + p.y;
            int next_x = get&amp;lt;2&amp;gt;(now.first) + p.x;

            if (isInside(next_z, next_y, next_x) &amp;amp;&amp;amp; !check[next_z][next_y][next_x] &amp;amp;&amp;amp; arr[next_z][next_y][next_x] == 0) {
                q.push({{next_z, next_y, next_x}, now.second + 1});
                day = max(now.second + 1, day);
                arr[next_z][next_y][next_x] = true;
            }
        }
    }
}

int main() {
    cin &amp;gt;&amp;gt; m &amp;gt;&amp;gt; n &amp;gt;&amp;gt; h;

    for (int k = 0; k &amp;lt; h; k++) {
        for (int i = 0; i &amp;lt; n; i++) {
            for (int j = 0; j &amp;lt; m; j++) {
                cin &amp;gt;&amp;gt; arr[k][i][j];
                if (arr[k][i][j] == 1)
                    tomatoes_pos.push_back({k, i, j});
            }
        }
    }
    bfs();
    for (int k = 0; k &amp;lt; h; k++) {
        for (int i = 0; i &amp;lt; n; i++) {
            for (int j = 0; j &amp;lt; m; j++) {
                if (!check[k][i][j] &amp;amp;&amp;amp; arr[k][i][j] == 0) {
                    return !(cout &amp;lt;&amp;lt; -1);
                }
            }
        }
    }
    cout &amp;lt;&amp;lt; day;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>BFS</category>
      <category>문제풀이</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/64</guid>
      <comments>https://hoondev.tistory.com/64#entry64comment</comments>
      <pubDate>Sun, 5 Apr 2020 19:08:14 +0900</pubDate>
    </item>
    <item>
      <title>BOJ 7576 - 토마토 문제풀이</title>
      <link>https://hoondev.tistory.com/63</link>
      <description>&lt;h3&gt;문제를 읽고 이해하기&lt;/h3&gt;
&lt;p&gt;철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vNNiI/btqDahyv183/rbQXQqlKyfZNusL39f1ce0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vNNiI/btqDahyv183/rbQXQqlKyfZNusL39f1ce0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vNNiI/btqDahyv183/rbQXQqlKyfZNusL39f1ce0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvNNiI%2FbtqDahyv183%2FrbQXQqlKyfZNusL39f1ce0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토의 인접한 곳은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;왼쪽, 오른쪽, 앞, 뒤 네 방향에 있는 토마토&lt;/b&gt;&lt;/span&gt;를 의미한다. &lt;b&gt;대각선 방향에 있는 토마토들에게는 영향을 주지 못하며&lt;/b&gt;, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 철수는 창고에 보관된 토마토들이 &lt;b&gt;며칠이 지나면 다 익게 되는지&lt;/b&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;그 최소 일수&lt;/b&gt;&lt;/span&gt;를 알고 싶어 한다.&lt;/p&gt;
&lt;p&gt;토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라. 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p&gt;첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수&lt;/b&gt;&lt;/span&gt;를 나타낸다. 단, 2 &amp;le; M,N &amp;le; &lt;b&gt;1,000&lt;/b&gt; 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. &lt;u&gt;&lt;b&gt;정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸&lt;/b&gt;&lt;/u&gt;을 나타낸다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p&gt;여러분은 토마토가 모두 익을 때까지의 최소 날짜를 출력해야 한다. 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, 토마토가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;모두 익지는 못하는 상황이면 -1을 출력해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;재정의와 추상화&lt;/h3&gt;
&lt;p&gt;익은 토마토가 하나가 아닐 수도 있기 때문에 여태껏 BFS를 하던 것 처럼&lt;b&gt; 특정 위치((0, 0)과 같은)에서만&lt;/b&gt; 시작하면 안됩니다.&lt;/p&gt;
&lt;p&gt;main()에서 창고에 있는 토마토의 상태를 받을 때, 토마토의 상태가 1인 경우(익은 토마토) 그 위치를 tomatoes_pos 라는 이름의 벡터에 담아둡니다. 그리고, 처음 BFS 함수를 진입할 때 처음 익은 토마토가 있는 위치를 모두 큐(Queue)에 담아둡니다.&lt;/p&gt;
&lt;p&gt;그 이후, 순서대로 큐에 있는 원소를 꺼내면 익은 토마토가 있는 모든 위치에서 각각 BFS를 시행할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;코드 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1586078055138&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;utility&amp;gt;
using namespace std;

// m은 가로 칸의 수, n은 세로 칸의 수
int m, n;
int arr[1001][1001];
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; tomatoes_pos;
bool check[1001][1001];
int day = 0;

typedef struct {
    int y, x;
} Position;

Position pos[4] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0 , 1 } };

bool isInside(int y, int x) {
    return y &amp;gt;= 0 &amp;amp;&amp;amp; x &amp;gt;= 0 &amp;amp;&amp;amp; y &amp;lt; n &amp;amp;&amp;amp; x &amp;lt; m;
}

void bfs() {
    queue&amp;lt;pair&amp;lt;pair&amp;lt;int, int&amp;gt;, int&amp;gt;&amp;gt; q;
    for (auto &amp;amp; tp : tomatoes_pos) {
        q.push({tp, 0});
        check[tp.first][tp.second] = true;
    }

    while (!q.empty()) {
        auto now = q.front();
        q.pop();

        for (auto &amp;amp; p : pos) {
            int next_y = now.first.first + p.y;
            int next_x = now.first.second + p.x;

            if (isInside(next_y, next_x) &amp;amp;&amp;amp; !check[next_y][next_x] &amp;amp;&amp;amp; arr[next_y][next_x] == 0) {
                q.push({{next_y, next_x}, now.second + 1});
                day = max(now.second + 1, day);
                arr[next_y][next_x] = true;
            }
        }
    }
}

int main() {
    cin &amp;gt;&amp;gt; m &amp;gt;&amp;gt; n;

    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            cin &amp;gt;&amp;gt; arr[i][j];
            if (arr[i][j] == 1)
                tomatoes_pos.push_back({i, j});
        }
    }

    bfs();

    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            if (!check[i][j] &amp;amp;&amp;amp; arr[i][j] == 0) {
                return !(cout &amp;lt;&amp;lt; -1);
            }
        }
    }
    cout &amp;lt;&amp;lt; day;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/63</guid>
      <comments>https://hoondev.tistory.com/63#entry63comment</comments>
      <pubDate>Sun, 5 Apr 2020 18:32:05 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 공부 계획 4/5 ~ 4/10</title>
      <link>https://hoondev.tistory.com/62</link>
      <description>&lt;h3&gt;공부 계획&lt;/h3&gt;
&lt;p&gt;기초 알고리즘 학습 계획을 바탕으로, 코딩테스트 주류 문제들을 모두 풀어보는 것을 목표로 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 114px;&quot; border=&quot;1&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 5일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;s&gt;BOJ 7576, 7569, 11047, 11399 문제 풀고 분석하기&lt;/s&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; (완료)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 6일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;s&gt;BOJ 2565, 9251, 1541, 1436 문제 풀고 분석하기&lt;/s&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(완료)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 7일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;s&gt;BOJ 1654, 1712, 2869, 7568, 2580 문제 풀고 분석하기&lt;/s&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(완료)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 8일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;s&gt;BOJ 12865, 2292, 10250, 3053 문제 풀고 분석하기&lt;/s&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(완료)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 9일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;s&gt;BOJ 2206, 14888, 2798, 2231, 1193 문제 풀고 분석하기&lt;/s&gt; &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(완료)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.3954%; text-align: center; height: 19px;&quot;&gt;4월 10일&lt;/td&gt;
&lt;td style=&quot;width: 83.6046%; height: 19px;&quot;&gt;&lt;s&gt;BOJ 2775, 2751, 10989, 2108, 11650, 11651, 10814, 10816&lt;/s&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;11066&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;(부분완료)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>일상/계획</category>
      <author>훈개발자</author>
      <guid isPermaLink="true">https://hoondev.tistory.com/62</guid>
      <comments>https://hoondev.tistory.com/62#entry62comment</comments>
      <pubDate>Sun, 5 Apr 2020 17:52:05 +0900</pubDate>
    </item>
  </channel>
</rss>