반응형
반응형

[백준] 1431. 시리얼 번호 (C++)

Algorithm|2022. 1. 23. 14:32
반응형
 

1431번: 시리얼 번호

첫째 줄에 기타의 개수 N이 주어진다. N은 50보다 작거나 같다. 둘째 줄부터 N개의 줄에 시리얼 번호가 하나씩 주어진다. 시리얼 번호의 길이는 최대 50이고, 알파벳 대문자 또는 숫자로만 이루어

www.acmicpc.net

Bubble Sort를 사용해 풀이하였다.

// 글자의 자리 수 합을 구하는 함수 
int s_number(string s) 
{
  int num = 0;

  for(int i=0; i<s.size(); i++)
  {
    if(48 <= s[i] && s[i] <= 57)
      num += s[i] - 48;
  }

  return num;
}

int main()
{
  int n; // 초기 입력 n
  string s;
  vector<vector<string>> store_s ; //문자열들을 저장하는 2차원 벡터
  vector<vector<int>> store_n ; //문자열들의 자리수 합을 저장하는 2차원 벡터

  for(int i=0; i<50;i++) //2차원 벡터 생성
  {
    vector<string> v1;
    vector<int> v2;
    store_s.push_back(v1);
    store_n.push_back(v2);
  }

  cin >> n; 
  for(int i=0; i<n; i++)
  { 
    cin >> s;
    store_s[s.size()-1].push_back(s); // 시리얼번호 저장 
    store_n[s.size()-1].push_back(s_number(s)); 
    // 시리얼 번호에 해당하는 자리수합 저장
  }



  
   for(int i=0; i<50; i++) //글자 길이가 50까지 이므로 50번 반복
    // Bubble Sort로 글자수에 따른 시리얼 번호 정렬
    for(int j=0; j<store_s[i].size(); j++)
    { 
      for(int k=0; k<store_s[i].size()-j-1; k++)
      { 
        string temp;
        int tmp;
        // 조건 2번에 따른 정렬
        if(store_n[i][k] > store_n[i][k+1])
        { 
          // 위치한 시리얼의 위치를 바꾼다
          temp = store_s[i][k]; 
          store_s[i][k] = store_s[i][k+1]; 
          store_s[i][k+1] = temp;
          // 위치한 시리얼의 자리수 합을 바꾼다
          tmp = store_n[i][k]; 
          store_n[i][k] = store_n[i][k+1]; 
          store_n[i][k+1] = tmp;
        }
        // 조건 3번에 따른 정렬
        else if(store_n[i][k] == store_n[i][k+1] && store_s[i][k] > store_s[i][k+1])
        // 위치한 시리얼의 위치를 바꾼다
        // 자리수 합은 같으므로 바꿀 필요는 없다 
        {
          temp = store_s[i][k]; 
          store_s[i][k] = store_s[i][k+1]; 
          store_s[i][k+1] = temp;
        }
        
      } 
    }


 // 출력
  for(int i=0; i<50; i++)
      for(int k=0; k< store_s[i].size(); k++)
        cout << store_s[i][k] << endl;
  

	return 0;
}
반응형

댓글()

[백준] 11478. 서로 다른 부분 문자열의 개수 (C++)

Algorithm|2022. 1. 17. 20:04
반응형
 

11478번: 서로 다른 부분 문자열의 개수

첫째 줄에 문자열 S가 주어진다. S는 알파벳 소문자로만 이루어져 있고, 길이는 1,000 이하이다.

www.acmicpc.net

 

O(n³) 인 방법으로 만들 수 있긴한데, <set>을 사용하는 게 아무래도 편할 것 같아서 set을 사용해서 풀었다.

 

int main(void) 
{
  set<string> a;
  string s;

  cin >> s;

  for(int i=0 ; i<s.size(); i++)
  { // window 크기 별로 입력 ex) 4글자면 1~4글자
    for(int k=0; k<s.size()-i; k++) 
    { // window slice
      a.insert( s.substr(k,i+1));
      // set 삽입
    }
      
  }

  cout << a.size();

  return 0;
}
반응형

댓글()

[Leetcode] Remove All Adjacent Duplicates In String (c++)

Algorithm|2022. 1. 16. 12:08
반응형
 

Remove All Adjacent Duplicates In String - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

스택을 사용해 간단하게 풀었다.

 

class Solution {
public:
    string removeDuplicates(string s) 
    {
        string ans;
        ans += s[0];
        
        for(int i=1; i<s.size(); i++)
        {

            if(ans.back() == s[i])
                ans.erase(ans.size()-1,ans.size());
            
            else
                ans += s[i];
        }
        
        return ans;
    }
};
반응형

댓글()

[백준] 17215. 볼링 점수 계산 (C++) (re)

Algorithm|2022. 1. 16. 11:51
반응형

 

 

17215번: 볼링 점수 계산

첫째 줄에 각 기회마다 소현이가 쓰러뜨린 볼링핀의 개수가 공백없이 주어진다. 이때 스트라이크는 S, 스페어는 P, 핀을 하나도 못 쓰러뜨린 것은 -으로 주어진다.

www.acmicpc.net

 

나름 조건 다 맞춰서 작성했는데, 아무리 봐도 어디가 문제인지 모르겠다...

다시 풀어보자,,,,

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>

using namespace std;



int main(void)
{
  string s;
  int score = 0;
  int tmp = 0; // 탐색 중인 점수를 저장
  int bonus = 0;
  int count = 0;
  int trys = 0;
  int s_count = 0;
  cin >> s;

  for(int i =0; i<s.size(); i++) //1번
  {


    if(48 < s[i] && s[i] < 58) //2번
    {
      score += s[i] - 48;
      tmp = s[i] - 48;
      trys++;
    }
    else if( s[i] == '-')
    {
      tmp = 0;
      trys++;
    }
    else if( s[i] == 'P')
    {
      score += 10 - tmp;
      
      trys++;
      tmp = 10 - tmp;
    }
    else if( s[i] == 'S')
    {
      score += 10;
      s_count ++;
      trys += 2;
      tmp = 10;
    }

    if(bonus > 0 && count < 9)
    {
      score += tmp;
      bonus--;
    }
    //cout << s[i] << "  " << count << "\n" ;
    if(trys == 2)
    {
      trys = 0;
      count++;
    }
    if( s[i] == 'P') bonus ++;
    else if( s[i] == 'S') bonus +=2;
    
    
  }
  if(s_count == 12) score = 300;
  cout << score;


  return 0;
}
반응형

댓글()

[백준] 2164. 카드2 (C++)

Algorithm|2022. 1. 14. 22:37
반응형
 

2164번: 카드2

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다. 이제 다음과 같은 동작을 카드가

www.acmicpc.net

 

int main(void)
{
  queue<int> q;
  int n;

  // 카드 수 입력
  cin >> n;
  
  // 입력한만큼 카드 추가
  for(int i=0; i<n; i++)
    q.push(i+1);


  // 마지막에 한장이 남으므로 n-1번 반복
  for(int i=0; i<n-1; i++)
  {
    q.pop(); // 맨 윗장을 지우고
    q.push( q.front() ); // 그리고 오게 된 카드를 맨 뒤에 놓음
    q.pop(); // 뒤로 보냈기에 중복 방지로 지움
  }
 
  // 정답 출력
  cout << q.front();

  return 0;
}

 

반응형

댓글()

[백준] 10867. 중복 빼고 정렬하기 (c++)

Algorithm|2022. 1. 14. 20:50
반응형
 

10867번: 중복 빼고 정렬하기

첫째 줄에 수의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째에는 숫자가 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

 

map의 특성을 이용해 풀었다.

중복을 막는 <set> 이란 라이브러리도 있는데 나중에 찾아봐야겠다.

 

num의 범위를 1~1000으로 생각해 풀어서 계속 헤맸는데,

-1000 ~ 1000이었다. 문제를 잘 읽도록 하자.

int main(void)
{
  int n = 0;
  int num = 0;
  vector<int> map(2001);

  cin >> n;

  for(int i=0; i<n; i++)
  {
    cin >> num;
    map[num+1000] = 1;
  }

  for(int i=0; i<=2001; i++)
  {
    if(map[i] == 1)
    {
      cout << i-1000 << " ";
    }
  }

  return 0;
}

 

반응형

댓글()

금융데이터와 머신러닝의 결합 실패 이유 - Qraft Technoledge

Machine Learning|2022. 1. 8. 14:58
반응형

 

금융과 딥러닝 - 금융 영역에서의 딥러닝은 어떻게 다른가?



GIGO (쓰레기를 넣으면 쓰레기가 나온다)


1. 시계열 특성 자체의 노이즈

미래 주가 = 현재 주가 + 정보 + 노이즈로 구성되는데, 시장에 존재하는 노이즈가 정보량보다 크기 때문에

주가를 예측한다는 것은 상당히 어려운 작업이다.

 

머신러닝 초기에 LSTM으로 가격을 예측하는 프로젝트들이 상당히 많은데,

대부분의 결과가 오른쪽으로 lagging된 것을 확인할 수 있다.

이미 주가가 오른 시점 이후에 주가가 오를 거라고 예측하는 모습을 볼 수 있는데,

이는 다음 주가가 현재 주가에 크게 의존하기에 이런 현상이 발생한다.

 

따라서 노이즈를 줄이기 위해 디노이즈 과정 필요하다.

학습 이전 데이터를 정제하는 방법으로 디노이즈의 대표적인 방법으로 이동평균Bilateral filter가 있고,

학습과정에서 자동으로 노이즈를 제거할 방법으로 Qraft는 CNN기반 Autoencoder 기반 시계열을 디노이즈 모델을 선택했다. 

 

2. 시계열 특성 종류 대비 짧은 시계열 길이

 

주가데이터나 거래량 같은 자산군 데이터는 매일매일 바뀌는 값이기에 누적된 데이터양이 방대하다.

하지만 금리, 인플레이션, 장단기 금리차 등의 macro data는 데이터양이 상당히 부족하다.

월 단위로 40년가량의 데이터가 있다고 하면, 12 x 40 = 480개의 데이터를 가지고 머신러닝을 train 해야 한다.

(이를 차원의 저주라고 한다)

 

그렇다면 실제 데이터가 부족한데 어떻게 모델을 학습시킬 것인가? 에 대한 문제가 생길 것이고,

이에 대한 해결책으로 기존 퀀트가 모델을 만드는 방식을 제시한다.

경제적 함의점을 내포하는 모델 설계하면 된다.

경제적 함의점은 사람의 주관이 개입할 수 도 있고 구체화하기는 불가능하다. 따라서 모델을 설계해야 한다.

 

즉, 시장에 존재하는 high level 팩터를 분석해 문제점을 해결한다.

예로 12-1m 모멘텀, 자산군 모멘텀 효과, 자산군 평균 회귀 효과, 확장적 통화정책, 긴축적 통화 정채, 단기부채 사이클, 장기부채 사이클, dynamic factor rotation 등을 고려할 수 있다.

 

 

3. Overfitting 발생과 해결

 

train 결과 비슷한 cost이지만 시작점(weight초기화)에 따라 overfitting 정도가 다르다.

L1, L2 Norm을 써도 데이터가 부족해 overfitting방지가 어렵다.

따라서 동시에 다수의 머신러닝을 학습한다. (Asynchronous Multi Network Learning)

training 중 test data를 가지고 Overfitting을 체크하게 되면, look-ahead bias가 발생하기에

따라서 별도의 vaildation data로 오버 피팅 감지한다.

 

overfitting이 생기는 또 다른 이유는 지금처럼 저금리 시대의 데이터가 충분하지 않거나, 지금까지 관찰된 적이 없던 부분을

어떻게 예측해야 하는지, 소수에 데이터로 overfitting이 발생하는 부분을 어떻게 처리해야하는지 대한 문제이다.

물론 관찰되지 않은 부분은 모르겠다고 하는 게 가장 좋다.

이에 대해서는 어떻게 모르겠다고 해야하는지, 모르는 부분은 어떻게 처리하는지는 Bayesian Inference로 확실성을 구하고

이에 따라 불확실성이 크면 투자를 보수적으로 하면 된다.

 

그 밖에 overfitting의 방지하는 방법으로 다음의 세 가지 방법이 있는데 Qraft에선 3. 의 방법을 채택했다고 한다.

1. Monte Carlo Dropout

2. Monte Carlo Batch Normalization

3. Deep Learning Regression + Gaussian Process Regression

(선지도 학습 후 GPR 학습)

 

Overfitting의 정도를 측정하는 metrics으로 주로 t- test를 사용한다고 한다.

 

 

4. 투자 이외의 머신러닝 활용

자연어 처리로 기업의 수익 보고를 분석해서 새로운 secotr etf를 창출하기도 한다.



 

 

 

반응형

댓글()

Project : Price and EPS NTM

Quant|2021. 12. 9. 20:39
반응형

🌒 Problem

평소 자주 사용하던 Koyfin에서 일부 회사 데이터를 유료로 제공하게 되었다.

🌓 Do

EPS 값과 가격 데이터만 있으면 충분히 나도 구현 가능할 것이다

 

🌔 Prepare

가격 데이터는 야후 파이낸스 api에서 제공해주므로 eps 데이터만 구해주면 된다.

 

🌕 Code

# Ticker 와 살펴볼 시작 날을 정한다

ticker = 'aapl'
date = '2020-01-01'

EPS 데이터 준비

야후 파이낸스에서 제공하는 eps는 가장 최근 분기가 아니라
현재 분기 전 2분기까지만 제공한다.

EX ) 애플 3분기 실적 2.0이라면, 애플 1분기 실적 1.8까지만 제공
따라서 가장 최근 분기와 그 이전 분기를 nasdaq.com에서 크롤링해 온다
또한 NTM 계산을 해야하므로 다음 분기들의 Consensus 값들도 크롤링한다.

NTM 계산방법 : 21년도 3분기 NTM
 = 21년도 4분기 eps + 22년도 1분기 eps + 22년도 2분기 eps + 22년도 3분기 eps 
# 셀레니움 설치

!pip install selenium
!apt-get update
!apt install chromium-chromedriver
#셀레니움 라이브러리 import

from selenium import webdriver
from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
from urllib.parse import quote_plus
from selenium.webdriver.common.keys import Keys
import time
from IPython.display import Image
import urllib
import time
# Colab에선 웹브라우저 창이 뜨지 않으므로 별도 설정한다.
# Colab 기본 설정 
options = webdriver.ChromeOptions()
options.add_argument('--headless')        # Head-less 설정
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'
options.add_argument('user-agent={0}'.format(user_agent))
driver = webdriver.Chrome('chromedriver', options=options)

#해당 url로 이동 ex : MSFT
url = "https://www.nasdaq.com/market-activity/stocks/"+ticker+"/earnings" 
driver.implicitly_wait(10)
driver.get(url)

consensus EPS 크롤링

import pandas as pd

# consensus EPS 크롤링
driver.implicitly_wait(10)
table = driver.find_element_by_class_name('earnings-forecast__section--quarterly')

# 통채로 추출한 테이블에서 필요한 consensus EPS 부분만 따로 추출
tbody = table.find_element_by_tag_name("tbody")
rows = tbody.find_elements_by_tag_name("tr")
eps = []

for index, value in enumerate(rows):
    body=value.find_elements_by_tag_name("td")[0]
    eps.append(body.text)

#다음 5개 분기의 consensus의 정확한 날을 모르므로, 최대한 미래 값으로 설정하였다.
eps_dict = {
    '2099-01-01': eps[0],
    '2099-01-02': eps[1],
    '2099-01-03': eps[2],
    '2099-01-04': eps[3],
    '2099-01-05': eps[4],
}

# dataframe 형태의 다음 5분기에 대한 consensus eps
eps = pd.DataFrame.from_dict(eps_dict, orient='index').rename(columns={0:'epsactual'})

실행 결과

현재 분기와 이전 분기 EPS 크롤링

import datetime

# 지금까지 발표된 eps 크롤링
table = driver.find_element_by_class_name('earnings-surprise__table')

# 문자열 형태로 받은 eps 데이터를 띄어쓰기 단위로 나눔
table_list = table.text.split()

# 15번째와 21번째에 현재분기와 이전분기 발표 날짜가 저장되어있고
## 여기서 사용하는 날짜 형식은 "2021-12-09" 이므로 해당 형태로 바꾸어준다. 
table_list[15] = table_list[15][6:] + '-' + table_list[15][:2] + '-' + table_list[15][3:5] 
table_list[21] = table_list[21][6:] + '-' + table_list[21][:2] + '-' + table_list[21][3:5]

# 크롤링한 eps 데이터를 딕셔너리 형태로 바꾸고, 이를 다시 dataframe 형태로 바꿔준다.
eps_b = {
    table_list[15] : table_list[16]
    ,
    table_list[21] : table_list[22]
}

# 날짜를 index로 설정하고, eps열의 이름을 'epsactual' 로 지정
eps_second = pd.DataFrame.from_dict(eps_b, orient='index').rename(columns={0:'epsactual'})

# 날짜가 내림차순으로 정렬 되어있어 다시 역순으로 정렬
eps_second = eps_second.iloc[::-1]

실행 결과

# 가격 데이터와 eps 데이터를 불러오기 위한 
## 야후 파이낸스 api 설치
!pip install yahoo_fin
!pip install yahoo_fin --upgrade
import pandas as pd
import yahoo_fin.stock_info as si

# price history
price = si.get_data(ticker)

# earnings history 
earnings_hist = si.get_earnings_history(ticker)

## index가 [4:] 인 이유는 미래 4개 분기의 eps 데이터를 불러오는데 
### None 값으로 가져오기 때문에 잘라버림
earnings_hist = earnings_hist[4:]

# list 형식으로 불러온 것을 dataframe 형태로 바꿔줌
earnings = pd.DataFrame(earnings_hist)

# 미래 -> 과거 순에서 과거 -> 미래 순으로 바꿈
earnings = earnings[['startdatetime','epsactual']].iloc[::-1]

# 날짜 10글자로 조정
earnings['startdatetime']  = earnings['startdatetime'].str.slice(start=0, stop=10)

# startdatetime -> Date 로 이름 변경
earnings = earnings.rename({'startdatetime': 'Date'}, axis=1)

# 날짜 data를 index로 설정
earnings = earnings.set_index('Date',inplace = False)

#크롤링한 eps data와 실제 eps를 합침
EPS_plus_forcast = earnings.append(eps_second, ignore_index=False)

## 날짜와 eps 가 중복되는 경우가 발생하는데, 가장 밑에 있는 요소를 살리고 
## 나머지는 다 지우도록 설정
EPS_plus_forcast = EPS_plus_forcast.loc[~EPS_plus_forcast.index.duplicated(keep='last')]
### ex : "2021-01-01" "2.1" , "2021-01-01" "2.3" 인 경우 
### 후자를 선택하고 이전 값은 제거


EPS_plus_forcast = EPS_plus_forcast.append(eps, ignore_index=False)
EPS_plus_forcast

실행 결과

# 왜인지는 모르겠는데 eps가 지수표현이 되어 출력돼서 
# 소수점 3글자만 출력하도록 설정
## 1.0+e0 -> 1.000
pd.options.display.float_format = '{:.3f}'.format
Pandas의 rolling 사용하면 NTM을 쉽게 계산할 수 있다.
하지만 rolling 기능은 자기 자신과 이전 N개의 합을 계산하므로,
EPS를 뒤집어서 계산해야 한다.

또한 NTM은 자기 자신의 eps는 포함하지 않으므로, rolling 이후, 자기 자신을 빼주어야 한다.
# ntm 계산용으로 eps 뒤집기
ntm_tmp = EPS_plus_forcast.iloc[::-1] 

# 자기 자신도 포함해서 더해버려서 5개를 더하고 자기자신을 빼면 미래의 4개가 됨
ntm_tmp = ntm_tmp['epsactual'].rolling(window = 5, min_periods=5).sum()

# ntm 다시 처음으로 되돌리기
ntm_tmp = ntm_tmp.iloc[::-1] 

# eps와 ntm의 요소가 str로 되어있는 경우가 있어 
# float 형태로 바꿔준다
ntm_tmp = ntm_tmp.astype('float')
EPS_plus_forcast = EPS_plus_forcast.astype('float')

# rolling 값에서 자기 자신 값을 빼준다.
NTM = ntm_tmp.to_frame(name='epsactual').sub(EPS_plus_forcast, fill_value = 0, axis = 0)

 가격 데이터와 EPS 데이터를 합쳐 하나의 dataframe으로 정리한다. 

# NTM과 가격데이터 융합
df = price.join(NTM)

# 실적 발표한 날 이전의 날들은 
## 그 이전 실적발표한 날의 NTM으로 설정한다
df = df.fillna(method='ffill')

# dataframe의 모든 요소를 출력
pd.set_option('display.max_row', None)

df.tail()

실행 결과

데이터 시각화

import matplotlib.pyplot as plt

# 처음 설정한 날짜부터 나타내도록 dataframe을 자른다. 
df = df.loc[date:]

# 가격 데이터(종가)를 그래프화
ax=df.plot(kind='line', y='close', color='DarkBlue', figsize=(20,10))

# NTM을 그래프화
ax2=df.plot(kind='line', y='epsactual', secondary_y=True,color='Red', ax=ax)

ax.set_ylabel('Price')
ax2.set_ylabel('EPS')

plt.show()

짜잔~

🌗 Part to supplement

사이트마다 다음 분기의 Consensus가 극명하게 달랐고 특히 'DOCU' 같은 경우 

nasdaq.com, 야후 파이낸스, investing 세 사이트 모두 달랐다.

 

이 문제는 추후 보완해볼 예정이다.

Koyfin의 NTM 계산 방법과 api와 사이트에서 제공하는 데이터를 사용해

내가 산출한 결과와 미세한 차이는 있지만, 엄청 크지는 않다.

반응형

'Quant' 카테고리의 다른 글

[Project] 증권사 리포트에 따라 사면 어떻게 될까??  (35) 2022.03.11
[Quant Strategy] Pair Trading with Long/Short  (17) 2022.02.20
[금융상품] 채권  (18) 2021.10.26
[금융상품] 원유  (20) 2021.10.18
[금융 상품] 금 / 은  (187) 2021.10.13

댓글()

[백준] 1158. 요세푸스 문제

Algorithm|2021. 12. 3. 17:15
반응형

Try 1 

배열로 풀었는데 뭔가 이상함 n = 4 / k =4 인 부분에서 오류 발생 

큐로 다시 풀어보고 배열도 틀린 점 고칠 예정

#include <vector>
#include <iostream>

using namespace std;

int main(void) 
{
  int n;
  int k;
  int count = 0;
  

  cin >> n >> k;


  vector<int> list(n);
  
  int idx = k-1;
  list[idx] = 1;

  cout << '<' << k << ", ";
  
  for(int i=0; i<n-1; i++)
  {
    while(count != k)
    {
      idx++;
      
      if(list[idx] == 0)
        count ++;

      if(idx == n)
        idx = 0;

      
    }
    
    count = 0;
    
    list[idx] = 1;

    if(i<n-2)
      cout << idx+1 << ", ";
    else 
      cout << idx+1 << ">";

  }

  return 0;
}

Try 2

탐색 idx를 다시 초기화 해주는 부분의 순서를 이상하게 했었음...

해결완료 

/* 수정한 부분 */
  
  for(int i=0; i<n-1; i++)
  {
    
    while(count != k)
    {
      idx++;

      if(idx == n)
        idx = 0;      
      
      if(list[idx] == 0)
        count ++;

    }
반응형

댓글()

[Programmers] 방문 길이 (C++)

Algorithm|2021. 11. 29. 17:07
반응형
 

코딩테스트 연습 - 방문 길이

 

programmers.co.kr

왜 간선 좌표로 파악해야하는지 이해하기

 

Try 1 실패 이유

1. 한 방향으로만 흔적을 남김 -> 한 방향으로 이동 시 역 방향으로 돌아왔을 때도 자취를 남겨야함

2. 배열을 생성했을 때, 배열의 각 요소의 초기값은 0이 아니라 dump값 임

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int solution(string dis) 
{
    int answer = 0;

    vector<vector<int>> w;
    for(int i=0; i<11; i++)
    {
        vector<int> v = {0,0,0,0,0,0,0,0,0,0,0};
        w.push_back(v);
    }
    
    int x = 5;
    int y = 5;
    w[y][x] = 1;
    
    for(int i=0; i<dis.size(); i++)
    {
        if(dis[i] == 'U' && y>=1)
            y--;
        else if(dis[i] == 'D' && y<=9)
            y++;
        else if(dis[i] == 'R' && x<=9)
            x++;
        else if(dis[i] == 'L' && x>=1)
            x--;
        else
        {
            w[y][x] = 0;
            answer--;
        }

        
        cout << x << " " << y << endl;
        
        
        answer++;
        if(w[y][x] == 1)
            break;
        w[y][x] = 1;
    }
    return answer;
}

 

Try 2 성공

#include <string>
#include <iostream>

using namespace std;

int solution(string dis) 
{
    int answer = 0;
    int map[11][11][11][11];
    
        
    int x = 5, y = 5;
    

    for(int i=0; i<dis.size(); i++)
    {   
        
      if(dis[i] == 'U' && y>=1)
      {
          if(map[y][x][y-1][x] !=1)
          {
            map[y-1][x][y][x] = 1;
            map[y][x][y-1][x] = 1;
            answer++;
          }
            y--;
      }
          
      else if(dis[i] == 'D' && y<=9)
      {
          if(map[y][x][y+1][x] != 1)
          {
            map[y][x][y+1][x] = 1;
            map[y+1][x][y][x] = 1;
            answer++;
          }
            y++;
      }
      else if(dis[i] == 'R' && x<=9)
      {
          if(map[y][x][y][x+1] != 1)
          {
            map[y][x][y][x+1] = 1;
            map[y][x+1][y][x] = 1; 
            answer++;
          }
          x++;
      }
      else if(dis[i] == 'L' && x>=1)
      {
         if(map[y][x][y][x-1] != 1)
         {
            map[y][x][y][x-1] = 1;
            map[y][x-1][y][x] = 1;
            answer++; 
         }
         x--;
      }
        
        cout << answer << endl;
        
    }
    
    return answer;
}
반응형

댓글()

[Programers] 약수의 개수와 덧셈 (C++)

Algorithm|2021. 11. 29. 16:36
반응형
 

코딩테스트 연습 - 약수의 개수와 덧셈

두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주

programmers.co.kr

제곱 수는 약수의 개수가 홀수 개라는 성질을 이용
int solution(int left, int right) 
{
    int answer = 0;
    
    for(int i=left ;i<=right; i++)
    {
        if(sqrt(i) - int(sqrt(i)) == 0)
            answer -= i;
        else
            answer += i;
    }
    
    return answer;
}
반응형

댓글()

[백준] 2941. 크로아티아 알파벳 (C++)

Algorithm|2021. 11. 29. 16:24
반응형
 

2941번: 크로아티아 알파벳

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다. 크로아티아 알파벳 변경 č c= ć c- dž dz= đ d- lj lj nj nj š s= ž z=

www.acmicpc.net

string compare의 결괏값을 자꾸만 헷갈린다. 
같으면 0을 출력한다.
int main(void)
{
    string s;
    int i = 0;
    int sum = 0;
    cin >> s;
    
    while(i < s.size())
    {
        if(s.substr(i,3).compare("dz=") == 0 && i<s.size()-2) 
            {
             i+=3;
            
            }
        else if(is_cro(s.substr(i,2)) && i<s.size()-1)
            {
              i+=2;
              
            }

        else 
        {
          i++;
          
        }
           
        
        sum++;
    }
    cout << sum;
}

bool is_cro(string s)
{
    
    if(s.compare("c=") == 0 || s.compare("c-") == 0||s.compare("d-") == 0||s.compare("lj") == 0||s.compare("nj")== 0 ||s.compare("s=") == 0||s.compare("z=")== 0)
        return true;
    return false;
}
반응형

댓글()

[Leetcode] 1154. Day of the Year (C++)

Algorithm|2021. 11. 29. 15:54
반응형
 

Day of the Year - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

실수 1월 2월은 윤년이어도 하루를 더하면 안됨
class Solution {
public:
    int dayOfYear(string date) 
    {
        int sum = 0;
        int year = stoi(date.substr(0,4));
        int mon = string_to_int(date.substr(5,2));
        int day = string_to_int(date.substr(8,2));
        vector<int> m_d = {31,28,31,30,31,30,31,31,30,31,30,31};
        
        if(mon == 1) return day;
        
        if(mon != 2)
            sum += is_yoon(year);
        
        for(int i=0; i<mon-1; i++)
        {
            sum += m_d[i];
        }
        
        return sum + day;
    }
    
    int is_yoon(int year)
    {
        if(year % 4 == 0)
        {
            if(year % 100 == 0)
            {
                if(year % 400 == 0)
                    return 1;
                return 0;
            }
            return 1;
        }
        return 0;
    }
    
    int string_to_int(string s)
    {
        if(s[0] == '0')
            return s[1] - '0';
        else
            return stoi(s);
    }
};
반응형

댓글()

[Programmers] 큰 수 만들기 (C++)

Algorithm|2021. 11. 29. 15:39
반응형
 

코딩테스트 연습 - 큰 수 만들기

 

programmers.co.kr

Try 1

1. K번째까지 탐색하며 가장 큰 수 전까지 제거
2. 확정된 처음 수 이후부터 끝까지 탐색하면서 
   다음 수와 비교했을 때 수가 증가한 경우 해당 수 제거
3. 제거함에도 불구하고, k가 남은 경우 k만큼 끝 자리 수 제거ㅌ
테스트 케이스는 다 맞았지만, 채점 결과 하나만 통과,,,
스택구조로 다시 풀어보겠다.
string solution(string s, int k) 
{
    int f_val = 0;
    int f_inx;
    
    for(int i=0; i<=k; i++) // 1. 과정
    {
        if(f_val < s[i] - '0')
        {
            f_val = s[i] - '0';
            f_inx = i;
        }
        
        
    }
    
    s = s.substr(f_inx, s.size() - f_inx); 
    k = k - f_inx;
    
    while(k > 0) // 2. 과정, 지워야할 숫자가 없다면 종료
    {
        vector<int> idx;
        
        for(int i=0; i<s.size()-1; i++) //다음 수가 커지는 경우 인덱스 저장
        {
            if(s[i] < s[i+1] && idx.size() < k)
                idx.push_back(i);
        }
        
        for(int i=0; i<idx.size(); i++) // 저장된 인덱스의 수 제거
        {
            s = s.erase(idx[i]-i,1);
        }
        
        k = k - idx.size(); //지워야 할 숫자들의 수 갱신
        if(idx.size() == 0) //다음 수가 커지는 경우가 없다면 끝내기
            break;
    }
    
    if(k > 1) // 3. 과정
        s = s.substr(0, s.size() - k);
    return s;
}

Try 2

테스트 케이스를 안 알려줘서 직접 다 쥐어짜내면서 하느라 죽는줄 알았다...

오름차순, 내림차순 섞으면서 해보고 오름차순으로만도 해보고, 내림차순만으로도 해보고

두자리 숫자에 하나만 지워보기도 하고, 테스크 케이스를 최대한 많이 굴려보는게 접근하기 좋다.

특히나 프로그래머스는 불친절한 감이 없지않아 있다...

 

아이디어는 아래 블로그를 적극적으로 활용했다.

 

큰 수 만들기(그리디, 탐욕법)[프로그래머스]

※ 저의 풀이가 무조건적인 정답은 아닙니다. 다른 코드가 좀더 효율적이고 좋을 수 있습니다. 다른사람들의 풀이는 언제나 참고만 하시기 바랍니다. 문제 주소입니다. https://programmers.co.kr/learn/c

mungto.tistory.com

string solution(string s, int k) 
{
    int f_val = 0;
    int f_inx = 0;
    string ans;
    
    for(int i=0; i <= k; i++) //처음 큰 수까지 추출 과정
    {
        if(f_val < s[i] - '0')
        {
            f_val = s[i] - '0';
            f_inx = i;
        }  
    }
    
    
    s = s.substr(f_inx, s.size() - f_inx); //추출한 값까지 제거
    
    ans += s[0];
    k = k - f_inx;
    
    f_inx = 1; //첫 자리는 정했으므로 그 다음 자리부터 시작
    
    while(k>0 && f_inx< s.size()) 
    { //더 이상 지울 수가 없거나 탐색 인덱스가 범위를 초과하면 중단
        f_val = 0; //수 비교 초깃값 0
        int tmp = f_inx; //탐색 시작점 저장
        
        for(int i=0; i<=k && tmp+i < s.size(); i++) 
        { //가장 큰 수의 인덱스를 찾는 과정
            if(f_val < s[tmp+i] - '0')
            {
                f_val = s[tmp+i] - '0';
                f_inx = tmp+i;
            }
        }
        
        ans += s[f_inx]; // 찾은 큰 수를 추가
        k -= (f_inx - tmp); 
        //큰 수의 인덱스와 시작점의 차이는 지운 숫자의 수임
        
        f_inx ++;  //큰 수의 인덱스 다음 인덱스부터 탐색 시작      
    }
    
    if(k>0) //k가 남아있는 경우 끝에서 k만큼 지워 주면 됨
      ans = s.substr(0, s.size()-k);
    else //다 지운 경우 탐색 인덱스 부터 끝부분까지 마저 채워주면 됨
      ans += s.substr(f_inx, s.size() - f_inx);
       
    
    return ans;
}
반응형

댓글()

[백준] 5355. 화성수학 (C++)

Algorithm|2021. 11. 26. 12:33
반응형
 

5355번: 화성 수학

겨울 방학에 달에 다녀온 상근이는 여름 방학 때는 화성에 갔다 올 예정이다. (3996번) 화성에서는 지구와는 조금 다른 연산자 @, %, #을 사용한다. @는 3을 곱하고, %는 5를 더하며, #는 7을 빼는 연산

www.acmicpc.net

 

int main()
{
  
  int T;
  
  vector<double> ans;
  int num_flag = 0;
  
  cin >> T;

  for(int i=0; i<T+1 ;i++) // 왜 T+1 을 해야 작동하는지 모르겠다.
  {
    double n;
    string num;

    getline(cin,num,'\n'); // 스페이스바 포함 입력
    
    for(int k=0; k < num.size(); k++)
    {
      if(num[k] == ' ' && num_flag == 0) //숫자부분 추출 과정
      {
        num_flag = 1;
        n = stof(num.substr(0,k));
      }
      if(num[k] == '@') n *= 3.0;
      else if(num[k] == '%') n+=5.0;
      else if(num[k] == '#') n-=7.0;
    }
    num_flag = 0;
    ans.push_back(n);
  }

  for(int k=1; k< ans.size(); k++) // 출력과정
  {
    cout.setf(ios::showpoint); // 끝의 0을 표시
    cout << fixed; //소수점 끝의 자리수만 고정
    cout.precision(2);

    cout << ans[k]<< endl; 
     
  }


  return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[Leetcode] 1154. Day of the Year (C++)  (1) 2021.11.29
[Programmers] 큰 수 만들기 (C++)  (1) 2021.11.29
[백준] 1476. 날짜 계산  (0) 2021.11.26
[백준] 1712. 손익분기점 (C++)  (7) 2021.11.25
[Programmers] 하샤드 수 (C++)  (1) 2021.11.25

댓글()

[백준] 1476. 날짜 계산

Algorithm|2021. 11. 26. 11:17
반응형
 

1476번: 날짜 계산

준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다. 지구를 나타

www.acmicpc.net

 

1년이 증가할 때마다
e s m을 1 증가하고 입력한 E S M과 동일한지 확인
다르다면, 1년을 다시 증가

중간에 e s m 이 각각의 범위를 초과할 때마다 1로 초기화시켜줌

 

int main()
{
  int E,S,M;
  int e = 1;
  int s = 1;
  int m = 1;
  int year = 1;
  cin >> E >> S >> M;

  while(1)
  {
    if(E == e && S == s && M == m)
      break;
    e ++;
    s ++;
    m ++;
    if(e == 16) e=1;
    if(s == 29) s=1;
    if(m == 20) m=1;

    year++;
  }
  cout << year;
  return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[Programmers] 큰 수 만들기 (C++)  (1) 2021.11.29
[백준] 5355. 화성수학 (C++)  (0) 2021.11.26
[백준] 1712. 손익분기점 (C++)  (7) 2021.11.25
[Programmers] 하샤드 수 (C++)  (1) 2021.11.25
[Leetcode] 258. Add Digits (C++)  (0) 2021.11.25

댓글()

[백준] 1712. 손익분기점 (C++)

Algorithm|2021. 11. 25. 17:14
반응형

 

 

1712번: 손익분기점

월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와

www.acmicpc.net

B(가변비용) 가 C(노트북 판매가)보다 크면 -1 리턴

손익 분기는 
C - B (노트북 한대의 순수익)이
A보다 커지는 시점이고

이는 (C - B) * n > A 로 생각 할 수 있다.
좌변과 우변이 같아지는 시점이 순이익이 0이 되는 지점이므로 이때보다 하나 더 팔면 된다.
int main() 
{
  int a,b,c;

  cin >> a >> b >> c;

  if(b >= c)
    cout << -1;
  else 
    cout << a/(c-b) + 1;

  return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 5355. 화성수학 (C++)  (0) 2021.11.26
[백준] 1476. 날짜 계산  (0) 2021.11.26
[Programmers] 하샤드 수 (C++)  (1) 2021.11.25
[Leetcode] 258. Add Digits (C++)  (0) 2021.11.25
[Leetcode] 342. Power of Four (C++)  (0) 2021.11.25

댓글()

[Programmers] 하샤드 수 (C++)

Algorithm|2021. 11. 25. 17:03
반응형
 

코딩테스트 연습 - 하샤드 수

양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다. 자연수 x를 입력받아 x가 하

programmers.co.kr

 

이전에 푼 알고리즘 문제를 참고함.

 

[Leetcode] 258. Add Digits (C++)

Add Digits - LeetCode Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. leetcode.com class Solution { publ..

gold-goose.tistory.com

bool solution(int x) 
{
    bool answer = true;
    int tmp;
    int sum = 0;
    int X = x;
    while(x != 0) // 각 자리수를 더하는 과정
    {
          tmp = x%10;
          sum += tmp;
          x = x / 10;
    }
    if(X % sum != 0)
        answer = false;
    return answer;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 1476. 날짜 계산  (0) 2021.11.26
[백준] 1712. 손익분기점 (C++)  (7) 2021.11.25
[Leetcode] 258. Add Digits (C++)  (0) 2021.11.25
[Leetcode] 342. Power of Four (C++)  (0) 2021.11.25
[백준] C++ 2775. 부녀회장이 될테야  (0) 2021.11.24

댓글()

[Leetcode] 258. Add Digits (C++)

Algorithm|2021. 11. 25. 16:53
반응형
 

Add Digits - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

class Solution {
public:
    int addDigits(int num) 
    {
        int tmp;
        int sum = 0;
        while(num > 9) // 아래 과정을 한 자리 수가 될 때까지 반복
        {
            while(num != 0) // 각 자리수를 더하는 과정
            {
                tmp = num%10;
                sum += tmp;
                num = num / 10;
            }   
            num = sum;
            sum = 0;
        }
        
        return num;
    }
};
반응형

댓글()

[Leetcode] 342. Power of Four (C++)

Algorithm|2021. 11. 25. 16:39
반응형

https://leetcode.com/problems/power-of-four/

 

Power of Four - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

n을 4로 계속 나누면서 인수분해를 진행

n의 인수 중 4를 제외한 값이 있다면, false 리턴 

class Solution {
public:
    bool isPowerOfFour(int n) 
    {
        if(n == 1) // 1일 경우 true 리턴
            return true;
        else if(n<1) //음수일 경우 false 리턴
            return false;
        
        while(1)
        {   
            if(n % 4 != 0) return false;
            else if(n == 4)
                break;
            
            n = n/4;
        }
        

        return true;    
    }
};
반응형

'Algorithm' 카테고리의 다른 글

[Programmers] 하샤드 수 (C++)  (1) 2021.11.25
[Leetcode] 258. Add Digits (C++)  (0) 2021.11.25
[백준] C++ 2775. 부녀회장이 될테야  (0) 2021.11.24
[Leetcode] 93. Restore IP Addresses  (0) 2021.11.23
[백준] 10757. 큰수 A+B  (1) 2021.11.23

댓글()