반응형

 

 

난독증이 있는 상수 이야기

 

풀이

 

입력은 세자리 문자열 2개가 들어온다

입력된 숫자(사실은 문자열임)의 배치를 반대로 바꾸어준 다음 비교하여 큰 값을 출력해주면 된다

(문자(char)에 저장된 숫자도 int형 숫자처럼 비교가 가능)

 

입력받은 문자열을 반대로 만든다음 맨 앞자리부터 비교한 다음 큰 수를 출력했다

반대로 만든 문자열의 한자리씩 비교하는 반복문 도중에

큰수가 있으면 출력 후 바로 리턴시켜서 종료했는데

 

이때 두 수가 같은 경우 반복문 내에서 결론이 나오지 않기때문에 반복문이 끝나고 둘 중 하나를 출력해주고 마무리시켰다

 

 

코드

 

#include <bits/stdc++.h>
using namespace std;
int main() {
	string str1,str2;
	cin >> str1;
	cin >> str2;
    
    //변환할 문자열
	string str1_, str2_;
    
    //문자열 반대로 변환
	for(int i=2; 0<=i; i--){
		str1_ += str1[i];
		str2_ += str2[i];
	}
    //앞자리부터 비교
	for(int i=0; i<3; i++){
		if(str1_[i] > str2_[i]){
			cout << str1_;
			return 0;
		}else if(str1_[i] < str2_[i]){
			cout << str2_;
			return 0;
		}
	}
    //반복문이 종료될때까지 큰수가 나타나지 않는다면 둘다 같은 수이므로 둘중에 하나를 출력했음
	cout << str1_;
	return 0;
}

 

 

출처 : https://www.acmicpc.net/problem/2908

 

2908번: 상수

상근이의 동생 상수는 수학을 정말 못한다. 상수는 숫자를 읽는데 문제가 있다. 이렇게 수학을 못하는 상수를 위해서 상근이는 수의 크기를 비교하는 문제를 내주었다. 상근이는 세 자리 수 두

www.acmicpc.net

 

반응형
반응형

백준 문자열 단어의 개수 풀이

다양한 사례를 생각하지 못해서 연달아 틀리다가 겨우 맞음

 

 

 

 

 

풀이

띄어쓰기 -> ' '

문자가 끝난것을 알려주는 기호 -> '\0'

 

이거 2가지를 미리 알고있으면 문제 푸는게 쉬움

 

 

char 배열의 마지막에는 null 문자가 있어 문자가 끝났다는것을 알수있고 억저고 ~

관련된 깊은 지식은 따로 검색 ㄱㄱ

 

일단 입력 범위가 굉장히 광범위하므로 입력의 크기인 백만개보다 하나 큰 만큼의 char 배열을 만든다음

그 중에서 실제로 사용자가 입력한 만큼만을 입력받아 처리했다

 

cin으로 입력을 받으면 띄어쓰기만 해도 입력이 종료되므로 평소와는 다른 입력 방식을 사용해야 함

getline 을 이용하여 사용자가 입력한 만큼 입력받아 미리 만들어둔 배열에 저장한 다음

 

문자 하나하나 확인하여 처리하면 됨

 

 

입력된 문자열이 (     ) 공백으로만 존재하거나 (     a) 공백부터 시작하여 마지막에 알파벳이 나올수도있으므로

띄어쓰기를 기본으로 숫자를 세지말고 알파벳을 기준으로 단어를 인식하게 함

 

아스키코드를 사용해서 문자의 알파벳 여부를 확인함

외우자

알파벳은 아스키코드 65~90, 97~122이다

 

배열에 저장된 각 문자를 반복해서 돌때 알파벳을 마주치면

그 다음 문자가 공백인지 확인 후, 공백이 맞다면 단어의 개수를 하나 증가시켜주고

공백이 아니라면 계속 알파벳이 나오고 있다는 뜻이므로 그냥 무시했다

 

알파벳이 아닌 배열의 끝을 알리는 \0 문자를 마주친다면

마지막 문자의 바로 앞에 위치한 문자가 공백인지 확인 후, 공백이 아니라면 그것 또한 단어이므로 ex) (a   b)

단어의 개수를 하나 증가시키고 반복을 멈추고 단어의 개수를 출력하면 된다

 

 

코드
#include <bits/stdc++.h>
using namespace std;
int main() {
	int cnt=0;
	char arr[1000001];
	cin.getline(arr, sizeof(arr));
	for(int i=0; i<=sizeof(arr); i++){
    		//a~z 또는 A~Z
		if(65<=arr[i] && arr[i]<=90 || 97<=arr[i] && arr[i]<=122){
			if(arr[i+1] == ' ') cnt++;
		}// ' ', '\0', '\n'
		else{
			if(arr[i] == '\0') {
				if(arr[i-1] != ' ') cnt++;
				break;
			}
		}
	}
	cout << cnt;
	return 0;
}

 

 

 

출처 : https://www.acmicpc.net/problem/1152

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열

www.acmicpc.net

 

반응형
반응형

2021 데브매칭 백엔드 상반기 문제를 풀어봤다

※그냥.. 최적이고 간에 해결하는것에 의의를 둔 풀이임

 

 

늘 그렇듯 1번 문제부터 고전했다.,

 

고전하는 중 질문하기 페이지를 구경하다가 문제에 대해 화가난 유저도 보았다

 

 

문제 요약

민우가 구입한 로또 번호 6개 중 동생이 랜덤하게 덧칠을 해서 알수없는게 n개 있는데

이 n개가 로또 정답일 때, 정답이 아닐 때 를 각각 구하면 됨

 

 

 

 

처음에 생각했던 방식

default_num, : 민우의 로또 번호 중 정답 로또 번호와 일치하는 것

ran_num : 민우의 번호 중 0 인 것

 

for문을 돌려 lottos(민우 로또 번호), win_nums(정답 로또 번호)를 비교하여 위의 변수에 ++; 해줌

 

민우와 정답 로또번호를 모두 비교해서 ran_num, default_num을 구한 뒤

미리 지정해둔 정답과 등수의 map을 이용해

answer에 각각 map[default_num+ran_num]과, map[default_num]을 삽입하도록 하였는데

 

테스트 케이스에서 계속 3개만 맞고 나머지 11개정도를 죄다 틀려버리는 사태가 발생해서

중간 중간 출력을 해보며 확인한 결과,

 

로또 번호를 비교하는 반복문을 수행할 때, 이미 0(ran_num)을 찾은 뒤에 또다시 같은 값을 확인해버리는 상황이 발생해서 문제가 생기는걸 확인함

 

 

해결법으로 2가지 정도를 생각해봤는데

1) 각각의 벡터를 정렬 시킨다음, 위의 방법처럼 for문으로 비교를 하는것과

2) 민우의 로또 번호에서 0을 찾은 다음, 6에서 그 개수를 뺀 나머지만큼만 반복문을 돌려서 수를 비교하는것 중

후자를 선택했다

 

※ 1번이 맞는 방법이 아닐수도 있다

 

 

map에 지정해둔 등수와 개수

맞힌 개수 등수
6 1
5 2
4 3
3 4
2 5
1 6
0 6

 

 

착오를 거쳐 수정한 방법

민우의 로또 번호 중 0의 갯수를 미리 모두 찾아 ran_num에 저장

그리고 민우의 번호인 lottos 벡터에서 0을 모두 지워버린 다음

그만큼 반복을 덜하도록 for문을 수정해주었다

 

#include<bits/stdc++.h>

using namespace std;

vector<int> solution(vector<int> lottos, vector<int> win_nums) {
    vector<int> answer;
    
    //최저 값, 랜덤 값 확인
    //default인 값 만큼은 갯수를 맞힐수있다
    //랜덤 값 만큼 디폴트 기준 위아래로 범위가 넓어짐    
    int default_num = 0;
    
    int ran_num = count(lottos.begin(), lottos.end(), 0);
    cout << "0의 값 : " << ran_num <<"\n";
    remove(lottos.begin(), lottos.end(), 0);
    
    //로또 번호 총 6개에서 민우 번호 중 0개인 만큼 제외하여
    //비교할 for문에 사용
    int len = lottos.size();
    int len1 = len-ran_num;
    int len2 = win_nums.size();
    
    //로또 정답과 민우 번호 비교에 사용
    int tmp;
    
    for(int i=0; i<len1; i++){
        tmp = lottos[i];      
        cout <<"\n tmp 값 : " << tmp << "\n";
        
        for(int j=0; j<len2; j++){            
            if(tmp == win_nums[j]){
                default_num++;
                cout <<"값이 같음, default 값 : " <<+ default_num << "\n";
                break;                
            }
        }
    }
       
    map<int,int> m;
    //맞은 갯수, 등수
    m[6] = 1;
    m[5] = 2;
    m[4] = 3;
    m[3] = 4;
    m[2] = 5;
    m[1] = 6;
    m[0] = 6;
           
    answer.push_back(m[default_num+ran_num]);    
    answer.push_back(m[default_num]);
    
    /* 맞게 들어갔는지 확인차 출력
    for(int i=0; i<2; i++){
        cout <<answer[i] << ", \n";
    }*/
    
    return answer;
}

최고 순위 : default_num + ran_num
> 맞은 로또 번호에 ran_num(0)이 추가로 정답일 경우
     
최저 순위 : default_num
> ran_num(0)이 로또 정답이 아닐 경우

 

map의 value 값은 중복이 가능하므로

m[1]=6, m[0] =6을 넣어줌

 

 

 

https://programmers.co.kr/learn/courses/30/lessons/77484?language=cpp 

 

코딩테스트 연습 - 로또의 최고 순위와 최저 순위

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호

programmers.co.kr

https://programmers.co.kr/learn/challenges

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

 

반응형
반응형

백준 10807번 개수 세기 문제

 

 

입력되는 정수의 개수 : 1개부터 100개까지 (1<= N =< 100)

입력되는 정수의 범위 : -100부터 100까지 (-100 <= v =< 100)

 

 

 

자연수가 아니라 정수 v가 -100부터 시작되는 값이어서 어떻게하지 하면서

문제를 보고 초반에는 약간 헤맸는데

 

 

다행히 정수 v의 범위가 자연수에 - 부호를 붙여주면 값은 동일하다고 판단해서

자연수 범위의 배열과 마이너스 일때 배열을 따로 추가해서 관리해보았다

 

입력한 정수의 값이 0보다 큰 경우, arr_plus에 증감연산자를 사용해서

특정 정수를 만날때마다 그 배열의 인덱스를 증가시켜 횟수를 적립시켰다

 

마찬가지로 0보다 작은 경우, arr_minus에 저장해서 관리함

 

사용배열 : arr_plus[100], arr_minus[100]

 

 

 

 

//수도코드

arr_plus[100] = 0;
arr_minus[100] = 0

int input,v;
cin >> input;

for(int i=0; i<input; i++){

	if(i>0) arr_plus[i]++;
	else arr_minus[-i]++;
}

cin >> v;

if (v>=0) cout << arr_plus[v];
else cout << arr_minus[-v];

 

 

대충 이렇게 작성해보았는데

 

 

그냥 후루룩 쓰다보니 간과했던게 배열의 범위를 100개가 아닌 101로 주었어야 했음

마이너스 값의 경우 상관없지만, 0부터 100까지의 값을 저장해주어야 하는

arr_plus에서 범위가 초과하는 문제가 생긴다

 

그래서 2번 틀렸다가 겨우 알아냄..

 

 

그렇게 초안에서 다듬고 틀린부분을 수정한 완성본이 아래의 코드

 

 

 

#include <bits/stdc++.h>
using namespace std;

int main() {
	
	int cnt,v;
	
	int arr_plus[101] = {0};
	int arr_minus[101] = {0};
	
	cin >> cnt;
	
	int tmp;
	
	for(int i=0; i<cnt; i++){
		cin >> tmp;
		
		if(tmp >=0){
			arr_plus[tmp]++;
		}
		else{
			arr_minus[-tmp]++;
		}
	}
	
	cin >> v;
	
	v>=0 ? cout << arr_plus[v] : cout << arr_minus[-v];
	
	return 0;
}

 

 

cnt : 맨 처음 입력인 입력할 정수의 개수

tmp : 입력받을 정수들

v : 찾을 정수

 

arr_plus[101] = 입력받은 tmp 중 0부터 100까지의 정수의 횟수를 저장할 배열

arr_minus[101] = 입력받은 tmp 중 -100부터 -1까지의 정수의 횟수를 저장할 배열

 

여기서 0을 plus에 둘지 minus 배열에 둘지는 그냥 본인 선택하기에 다를듯

 

 

마지막에 삼항연산자 문법을 사용해서 if else문을 줄여보았다

 

 

 

삼항연산자 문법

 

 

 

 

 

출처 : 

 

 

10807번: 개수 세기

첫째 줄에 정수의 개수 N(1 ≤ N ≤ 100)이 주어진다. 둘째 줄에는 정수가 공백으로 구분되어져있다. 셋째 줄에는 찾으려고 하는 정수 v가 주어진다. 입력으로 주어지는 정수와 v는 -100보다 크거

www.acmicpc.net

 

 

 

C 언어 코딩 도장: 20.2 삼항 연산자 사용하기

먼저 삼항 연산자를 사용하기 전에 if 조건문으로 num1의 값이 참이면 num2에 100을 할당하고, 거짓이면 num2에 200을 할당하는 코드를 만들어보겠습니다. if_else.c #include int main() { int num1 = 5; int num2; if

dojang.io

 

반응형

+ Recent posts