programmers.co.kr/learn/courses/30/lessons/64064#

 

코딩테스트 연습 - 불량 사용자

개발팀 내에서 이벤트 개발을 담당하고 있는 무지는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량 ��

programmers.co.kr

문제 설명


개발팀 내에서 이벤트 개발을 담당하고 있는 무지는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량 사용자라는 이름으로 목록을 만들어서 당첨 처리 시 제외하도록 이벤트 당첨자 담당자인 프로도 에게 전달하려고 합니다. 이 때 개인정보 보호을 위해 사용자 아이디 중 일부 문자를 '*' 문자로 가려서 전달했습니다. 가리고자 하는 문자 하나에 '*' 문자 하나를 사용하였고 아이디 당 최소 하나 이상의 '*' 문자를 사용하였습니다. 무지와 프로도는 불량 사용자 목록에 매핑된 응모자 아이디를 제재 아이디 라고 부르기로 하였습니다. 예를 들어, 이벤트에 응모한 전체 사용자 아이디 목록이 다음과 같다면

 

접근 방법


먼저 banned_id 리스트로 만들수 있는 모든 경우의 수를 구합니다. 그 과정에서 만들어진 목록을 string으로 하나로 만들도록 했습니다. 

그리고 이렇게 만들어진 string 백터에서 중복을 제거하면  끝~ level 3번 치고 쉬운 문제였네요 ^0^~

 

코드 


#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

vector<int>astro;
vector<string>ans;
vector<string>container;
bool isused[10];
int cnt=0;
bool compare(string a,string b){
    if(a.length()>b.length()) return false;
    else if(a.length()<b.length()) return true;
    else return a<b;
}
void gd(vector<string> user_id,vector<string> banned_id){
    if(cnt==banned_id.size()){
        vector<string>a;
        a=container;
        sort(a.begin(),a.end(),compare);
        string temp="";
        for(int i=0;i<a.size();i++){
            temp+=a[i];
            temp+=" ";
        }
        ans.push_back(temp);
        return;
    }
    for(int i=0;i<user_id.size();i++){
        //이미 사용된 아이디 제외
        if(isused[i]==true)continue;
        string s1= user_id[i];
        int correct_cnt=0;
        //길이 확인
        if(s1.size()==banned_id[cnt].size()){
            for(int j=0;j<s1.size();j++){
                //각각의 요소 비교
                if(banned_id[cnt][j]=='*'||s1[j]==banned_id[cnt][j]){
                    correct_cnt++;
                    continue;
                }
                else break;
            }
            //같을 경우
            if(correct_cnt==s1.size()){
                container.push_back(s1);
                isused[i]=true;
                cnt++;
                gd(user_id,banned_id);
                isused[i]=false;
                cnt--;
                container.pop_back();
            }
        }
        
    }
}
int solution(vector<string> user_id, vector<string> banned_id) {
    int answer = 0;
    memset(isused,false,sizeof(isused));
    gd(user_id,banned_id);

    sort(ans.begin(),ans.end());
    ans.erase(unique(ans.begin(),ans.end()),ans.end());

    return ans.size();
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/17676?language=cpp

 

코딩테스트 연습 - [1차] 추석 트래픽

입력: [ 2016-09-15 20:59:57.421 0.351s, 2016-09-15 20:59:58.233 1.181s, 2016-09-15 20:59:58.299 0.8s, 2016-09-15 20:59:58.688 1.041s, 2016-09-15 20:59:59.591 1.412s, 2016-09-15 21:00:00.464 1.466s, 2016-09-15 21:00:00.741 1.581s, 2016-09-15 21:00:00.748

programmers.co.kr

문제 설명


이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다. 

 

입력 형식

1. solution 함수에 전달되는 lines 배열은 N(1 ≦ N ≦ 2,000)개의 로그 문자열로 되어 있으며,

각 로그 문자열마다 요청에 대한 응답완료시간 S와 처리시간 T가 공백으로 구분되어 있다.

2. 응답완료시간 S는 작년 추석인 2016년 9월 15일만 포함하여 고정 길이 2016-09-15 hh:mm:ss.sss 형식으로 되어 있다.

3. 처리시간 T는 0.1s, 0.312s, 2s 와 같이 최대 소수점 셋째 자리까지 기록하며 뒤에는 초 단위를 의미하는 s로 끝난다.

(예를 들어, 로그 문자열 2016-09-15 03:10:33.020 0.011s은 2016년 9월 15일 오전 3시 10분 **33.010초**부터 2016년 9월 15일 오전 3시 10분 **33.020초**까지 **0.011초** 동안 처리된 요청을 의미한다.) (처리시간은 시작시간과 끝시간을 포함)

4. 서버에는 타임아웃이 3초로 적용되어 있기 때문에 처리시간은 0.001 ≦ T ≦ 3.000이다.

5. lines 배열은 응답완료시간 S를 기준으로 오름차순 정렬되어 있다.

 

출력형식

- solution 함수에서는 로그 데이터 lines 배열에 대해 초당 최대 처리량을 리턴한다.

 

접근 방법


먼저 시간을 분류하고 초 단위 통일했습니다. 처음 방법은 초기 시간 중 가장 작은 시간부터 시작해서 초기 시간 중 가장 긴 시간까지 탐색을 하는 방법으로 진행했습니다!! (시간 초과가 날걸 알았지만 ㅠㅠ 방법이 생각이 안 나서....)

이후에는 시간을 서치 하면서 오차범위로 탐색하는 방법을 선택하여 성공하게 되었습니다.

 

ps) c++ 부동소수점 비교 ***

c++로 구현하면서 double로 저장된 값들을 비교할때 a≥b 같이 사용하면 같은 값이라도 거짓으로 나오는 경우가 있다.

부동소수점 표현에서 발생되는 오차때문에 직접적으로 비교하는건 정확하지 않다.

그래서 위의 코드에서도 epsilon이라는 작은 허용 오차 범위를 정해서

a≥b → abs(a-b)≥epsilon 의 형태로 바꿔서 비교해야한다.

 

코드 


[바른 코드]

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

#define abs(x) x<0 ? -x : x
#define epsilon 0.001

using namespace std;


vector<pair<double,double>>range;
vector<int>ans;
int solution(vector<string> lines) {
    int answer = 0;
    for(int i=0;i<lines.size();i++){
        string data=lines[i];
        double hour=stod(data.substr(11,2))*3600;
        double minute=stod(data.substr(14,2))*60;
        double sec=stod(data.substr(17,6));
        double Time=stod(data.substr(24,data.size()-24-1));
      
        double second_time = hour+minute+sec;
        double first_time =second_time-Time; //0.001 더해줄것
        if(first_time<0)first_time=0.000;
        else first_time=first_time+0.001;
        range.push_back(make_pair(first_time,second_time));
    }
    double minimum=9876543.0,maximum=0.0;
    for(int i=0;i<range.size();i++){
        minimum=min(range[i].first,minimum);
        maximum=max(range[i].first,maximum);
    }
    int cnt;
    double start=minimum;
    
    for(int i=0;i<range.size();i++){
    	double begin = range[i].second;
    	double end = begin+0.999;
    	cnt=0;
    	for(int j=i;j<range.size();j++){
    		if(abs(range[j].second-begin)>=epsilon && abs(range[j].first-end)<=epsilon) cnt++;
    		
    	}
    	//최대값 저장
    	answer=max(answer,cnt);
    }
    return answer;
}

[오류 코드]

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<pair<double,double>>range;
vector<int>ans;
int solution(vector<string> lines) {
    int answer = 0;
    for(int i=0;i<lines.size();i++){
        string data=lines[i];
        double hour=stod(data.substr(11,2))*3600;
        double minute=stod(data.substr(14,2))*60;
        double sec=stod(data.substr(17,6));
        double Time=stod(data.substr(24,data.size()-24-1));
      
        double second_time = hour+minute+sec;
        double first_time =second_time-Time; //0.001 더해줄것
        if(first_time<0)first_time=0.000;
        else first_time=first_time+0.001;
        range.push_back(make_pair(first_time,second_time));
    }
    double minimum=9876543.0,maximum=0.0;
    for(int i=0;i<range.size();i++){
        minimum=min(range[i].first,minimum);
        maximum=max(range[i].first,maximum);
    }
    int cnt;
    double start=minimum;
    
    while(true){
        cnt=0;
        for(int i=0;i<range.size();i++){
            if(start > range[i].second || start+1 < range[i].first )continue;
            else cnt++;
        }
        
        answer=max(answer,cnt);
        if(start+0.999>=maximum)break;
        else start=start+0.001;
        //printf("%lf \n",start);
        
    }
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/42889

 

코딩테스트 연습 - 실패율

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스��

programmers.co.kr

문제 설명


슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다. 이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.

 

실패율 = 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

 

전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

 

접근 방법


각 스테이지 함수를 별도로 만들어 현재 스테이지만큼 개수를 늘려나갔습니다. 다음으로 전체 Total 변수를 통해 실패율을 계산하고 Total에서 차감하고 실패율 계산을 반복하면 됩니다.

(단, Total 이 0인 경우는 NAN이 되기 때문에 이 부분을 처리해주셔야 합니다~)

 

코드 


#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;
bool comp(pair<double,int> a,pair<double,int>b){
    if(a.first>b.first)return true;
    else{
        if(a.first==b.first) return a.second<b.second;
        else return false;
    }
}
vector<int> solution(int N, vector<int> stages) {
    vector<int> answer;
    int stage_reach[510]={0,};
    memset(stage_reach,0,sizeof(stage_reach));
    
    for(int i=0;i<stages.size();i++) stage_reach[stages[i]]++;
    
    int total=stages.size();
    vector<pair<double,int> >ans;
    for(int i=1;i<=N;i++){
        double d;
        if(total==0){
            d=0;
            ans.push_back(make_pair(d,i));
        }
        else{
            d= double(stage_reach[i])/double(total);
            ans.push_back(make_pair(d,i));
        }
        total-=stage_reach[i];
    }
    sort(ans.begin(),ans.end(),comp);
    for(int i=0;i<ans.size();i++) answer.push_back(ans[i].second);
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/17682

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr

문제 설명


 

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다. 갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

 

1. 다트 게임은 총 3번의 기회로 구성된다.

2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.

3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.

4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.

5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)

6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)

7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)

8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.

9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다. 

 

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

 

접근 방법


이번 문제도 복잡하지 않고 주어진 흐름대로 따라가면 쉽게 해결할 수 있습니다!!

1. 숫자 파악

2. (S),(D),(T)에 따라 pow 를 해줍니다.

3. "*"일 경우 앞 뒤 모두 두배를 해줍니다. (단, 뒤에가 없을 경우 구분해주어야 합니다~)

3-1. "#"의 경우 현재 수의 -1을 곱해주면 되겠습니다~

 

코드 


#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <vector>
using namespace std;

int solution(string dartResult) {
    int answer = 0;
    vector<int>ans;
    string number="";
    for(int i=0;i<dartResult.size();i++){
        string s="";
        s+=dartResult[i];
        if(dartResult[i]>='0'&&dartResult[i]<='9'){
            number+=s;
        }
        else if(s.compare("S")==0||s.compare("D")==0||s.compare("T")==0){
            if(s.compare("S")==0){
                ans.push_back(pow(stoi(number),1));
            }
            else if(s.compare("D")==0){
                ans.push_back(pow(stoi(number),2));
            }
            else if(s.compare("T")==0){
                ans.push_back(pow(stoi(number),3));
            }
            number="";
        }
        else if(s.compare("*")==0||s.compare("#")==0){
            if(s.compare("#")==0){
              ans[ans.size()-1] =ans[ans.size()-1]*(-1);
            }
            else if(s.compare("*")==0){
                //뒤에 있는지 체크
                if(ans.size()>1){
                     ans[ans.size()-1] =ans[ans.size()-1]*2;
                     ans[ans.size()-2] =ans[ans.size()-2]*2;
                }
                else{
                    ans[ans.size()-1] =ans[ans.size()-1]*2;
                }
            }
        }
    }
    for(int i=0;i<ans.size();i++) answer+=ans[i];
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/12982

 

코딩테스트 연습 - 예산

S사에서는 각 부서에 필요한 물품을 지원해 주기 위해 부서별로 물품을 구매하는데 필요한 금액을 조사했습니다. 그러나, 전체 예산이 정해져 있기 때문에 모든 부서의 물품을 구매해 줄 수는 ��

programmers.co.kr

문제 설명


최대한 많은 부서의 물품을 구매해 줄 수 있도록 하려고 합니다. 물품을 구매해 줄 때는 각 부서가 신청한 금액만큼을 모두 지원해 줘야 합니다. 예를 들어 1,000원을 신청한 부서에는 정확히 1,000원을 지원해야 하며, 1,000원보다 적은 금액을 지원해 줄 수는 없습니다.

부서별로 신청한 금액이 들어있는 배열 d와 예산 budget이 매개변수로 주어질 때, 최대 몇 개의 부서에 물품을 지원할수 있을지~

제한사항

1. d는 부서별로 신청한 금액이 들어있는 배열이며, 길이(전체 부서의 개수)는 1 이상 100 이하입니다.

2. d의 각 원소는 부서별로 신청한 금액을 나타내며, 부서별 신청 금액은 1 이상 100,000 이하의 자연수입니다.

3. budget은 예산을 나타내며, 1 이상 10,000,000 이하의 자연수입니다.

 

접근 방법


매우 간단하죠~ ^^ 그리디로 풀수 있지만 예산이 아니고 최대 개수이므로 sorting 하고 예산이 넘어가면 STOP!!! 끝입니다 

 

코드 


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

using namespace std;

int solution(vector<int> d, int budget) {
    int answer = 0,total=0;
    sort(d.begin(),d.end());
    for(int i=0;i<d.size();i++){
        answer++;
        total+=d[i];
        if(total>budget) {
            answer-=1;
            break;
        }
    }
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/17681

 

코딩테스트 연습 - [1차] 비밀지도

비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다

programmers.co.kr

문제 설명


네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

 

1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 공백(" ) 또는벽(#") 두 종류로 이루어져 있다.

2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 지도 1과 지도 2라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.

3. 지도 1과 지도 2는 각각 정수 배열로 암호화되어 있다.

4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

 

 

접근 방법


1. string을 int로 바꾼다음 이진법으로 변환합니다.

2. 만약 이진법으로 바꾼 사이즈가 3이라면 전체 메트릭스 사이즈에서 남은 사이즈를 앞에 0으로 채워줍니다 (초기에 0으로 초기화 하는게 빠르겠죠?)

3. 마무리는 간단하게 두개의 배열을 합치면서 둘다 공백이면 " "을 넣어주고 아니면 "#"을 넣어줍니다~

끝!! 이번 문제는 간단하고 쉽죠 ^0^

 

코드 


#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<string> solution(int n, vector<int> arr1, vector<int> arr2) {
    vector<string> answer;
    int map1[n][n];
    int map2[n][n];
    memset(map1,0,sizeof(map1));memset(map2,0,sizeof(map2));
    
    for(int i=0;i<arr1.size();i++){
        int num=arr1[i];
        int mook=num,res=0;
        vector<int>temp;
        while(true){
            res=mook%2;
            mook=mook/2;
            if(mook==0){
                temp.push_back(res);
                break;
            }
            else temp.push_back(res);
            
        }
        int cnt=0;
        reverse(temp.begin(),temp.end());
        for(int j=0;j<temp.size();j++){
            map1[i][n-temp.size()+(j)]=temp[j];
        }
    }
    
    for(int i=0;i<arr2.size();i++){
        int num=arr2[i];
        int mook=num,res=0;
        vector<int>temp;
        while(true){
            res=mook%2;
            mook=mook/2;
            if(mook==0){
                temp.push_back(res);
                break;
            }
            else temp.push_back(res);
            
        }
        int cnt=0;
        reverse(temp.begin(),temp.end());
        for(int j=0;j<temp.size();j++){
            map2[i][n-temp.size()+(j)]=temp[j];
        }
    }
    for(int i=0;i<n;i++){
        string s="";
        for(int j=0;j<n;j++){
            if(map1[i][j]==0&&map2[i][j]==0) s+=" ";
            else s+="#";
        }
        answer.push_back(s);
    }
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

문제 설명


이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

 

- 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.

- 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.

- 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.

- 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
(만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.)

 

순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

 

접근 방법


왼쪽은 왼쪽 엄지만 이용하고 오른쪽은 오른쪽 엄지만 이용하기 때문에 문제가 되지 않지만 가운데의 경우가 문제입니다.

이 경우 저는 좌표식으로 거리를 구할 수 있도록 했습니다. 먼저 '0'을 '11'로 설정하고 '*'을 '10'으로 '#'을 12로 설정했습니다.

그 후 3으로 나누어 x(나머지), y(몫) 좌표를 만들었습니다.

(단, 맨 오른쪽의 경우 나머지가 0인경우는 몫을 하나 줄이고 나머지를 3 더해줌으로써 좌표에 맞추어 수정해주었습니다)

이후 왼쪽 엄지와 오른쪽 엄지와의 거리를 비교해주도록 했습니다. 엄지가 이동하고 엄지의 좌표도 이동해주는 것은 필수~!!!

 

코드 


#include <string>
#include <vector>
#include <iostream>
using namespace std;

string solution(vector<int> numbers, string hand) {
    string answer = "";
    //(0,1)(0,2)(1,0);
    //(1,1)(1,2)(2,0);
    //(2,1)(2,2)(3,0);
    //(3,1)(3,2)(4,0);
    
    int left_y=3,left_x=1;
    int right_y=3,right_x=3;
    for(int i=0;i<numbers.size();i++){
        int pad_num=numbers[i];
        if(pad_num==0){pad_num=11;}
        
        int mook=pad_num/3;
        int res=pad_num%3;
        
        if(res==0){
            mook-=1;res+=3;
        }
        //
        if(res==1){
            answer+="L";
            left_y=mook;left_x=res;
            continue;
        }
        else if(res==3){
            answer+="R";
            right_y=mook;right_x=res;
        }
        else if(res==2){
            //left와의 거리,right와의 거리(중간)
            int left_distance=abs(left_y-mook)+abs(left_x-res);
            int right_distance=abs(right_y-mook)+abs(right_x-res);
            if(left_distance<right_distance){
                answer+="L";
                left_y=mook;left_x=res;
            }
            else if(left_distance>right_distance){
                answer+="R";
                right_y=mook;right_x=res;
            }
            else if(left_distance==right_distance){
                if(hand.compare("right")==0){
                    answer+="R";
                    right_y=mook;right_x=res;
                }
                else{
                    answer+="L";
                    left_y=mook;left_x=res;
                }
            }
            
        }
        
    }
    return answer;
}

funny algorithm 0_<

programmers.co.kr/learn/courses/30/lessons/17687

 

코딩테스트 연습 - [3차] n진수 게임

N진수 게임 튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다. 숫자를 0�

programmers.co.kr

문제 설명 


튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다.

이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다.

- 숫자를 0부터 시작해서 차례대로 말한다. 첫 번째 사람은 0, 두 번째 사람은 1, … 열 번째 사람은 9를 말한다.

- 10 이상의 숫자부터는 한 자리씩 끊어서 말한다. 즉 열한 번째 사람은 10의 첫 자리인 1, 열두 번째 사람은 둘째 자리인 0을 말한다.

이렇게 게임을 진행할 경우,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, … 순으로 숫자를 말하면 된다.

한편 코딩 동아리 일원들은 컴퓨터를 다루는 사람답게 이진수로 이 게임을 진행하기도 하는데, 이 경우에는
0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, … 순으로 숫자를 말하면 된다.

이진수로 진행하는 게임에 익숙해져 질려가던 사람들은 좀 더 난이도를 높이기 위해 이진법에서 십육진법까지 모든 진법으로 게임을 진행해보기로 했다. 숫자 게임이 익숙하지 않은 튜브는 게임에 져서 벌칙을 받는 굴욕을 피하기 위해, 자신이 말해야 하는 숫자를 스마트폰에 미리 출력해주는 프로그램을 만들려고 한다. 튜브의 프로그램을 구현하라.

 

 

접근 방법


풀이법은 간단합니다. t는 구해야 하는 개수가 되기때문에 돌려말하면 t번의 턴 만큼 진행한다는 것입니다. 또한 전체 맴버의 수가 m이므로 m*t만큼의 진수 리스트를 구해주시면 됩니다. 

저는 이진법을 나누기 몫 방법으로 구하고 reverse를 이용하여 추가하는 식으로 진행했기 때문에 m*t 와 같거나 큰 경우에 진수 변환를  멈추면 됩니다 ^^ 그리고 해당 번호에 해당하는 번호만 뽑으면 완료~

 

코드 


#include <string>
#include <vector>
#include <iostream>
using namespace std;
vector<string>container;
string solution(int n, int t, int m, int p) {
    string answer = "";
    // 0 1 1 0 1 1 1 0 0 101 110
    //구해야할 총길이
    int len=m*t;
    p=p-1;
    //2*0,2*1,2*15
    //n진법으로 길이만큼 구하기
    int cnt=0;
    int number=0;
    while(true){
        if(cnt==len)break;
        int mook=number,res=0;
        vector<string>temp;
        while(true){
            res=mook%n;
            mook=mook/n;
            string s1="";
            if(res>=10){
                if(res==10)s1="A";else if(res==11)s1="B";
                else if(res==12)s1="C";else if(res==13)s1="D";
                else if(res==14)s1="E";else if(res==15)s1="F";
            }
            else s1=to_string(res);

            temp.push_back(s1);
            cnt+=s1.size();
            
            if(mook==0) break;
          
        }
        for(int i=temp.size()-1;i>=0;i--){
            container.push_back(temp[i]);
        }//여기서는 reverse 함수를 써도됩니다. 저는 순간 잊고 있어서;;;;
        temp.clear();
        number++;
        if(cnt>=len)break;
    }
    
    int idx=p,cnt2=0;
    while(true){
        if(cnt2==t)break;
        else{
            answer+=container[idx];
            idx+=m;cnt2++;
        }
    }
    return answer;
}

fuuny algorithm0_<

+ Recent posts