반응형

백준 심화1 그룹단어 체크 c++ 풀이

 

 

 

 

 

 

풀이

a b c d e f g h i j k l m n o p q r s t u v w x y z
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

문자열=아스키코드

알파벳 소문자 a부터 소문자 z까지 크기가 26인 배열을 만든다음 0으로 초기화

벡터에 반복하여 저장한 입력 문자열의 각 문자에 접근한 값에서 97을 빼준다음

그 위치에 해당하는 알파벳의 값을 1 증가시켜줌

 

이때 문자열 aab인 경우 예외가 되므로 이전 문자와 현재 문자가 다른 경우에만 배열 값을 증가시킴

배열 값이 1을 초과하는 경우, 이전에 나온 문자가 한번 더 나와 그룹단어가 아니게 되므로 세지않음

 

사용 변수 용도 설명

 

cnt : 문자열 반복해서 입력받을 횟수

ans : 그룹 단어 확인 후 출력할 갯수 (정답)

vector<string> : 반복해서 입력받은 문자열 저장하는 벡터

int arr[] : 알파벳 중복 횟수 확인용

isGroupWord : 그룹 단어가 아닌 경우 구분 용도

 

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int cnt = 0;
    cin >> cnt;
    int ans = 0;
    vector<string> str;
    bool isGroupWord = true;
    for(int i=0; i<cnt; i++){
        string s = "";
        cin >> s;
        str.push_back(s);
    }
    for(int i=0; i<str.size(); i++){
        int arr[26] = {0,};
        string s = str[i];
        for(int j=0; j<s.length(); j++){
            if(s.length() == 1){
                cout << "글자 수 한 개일 때 : " << s << "\n";
                break;
            }
            if(s[j] != s[j-1]){
                cout << "현재 문자 : " << s[j] << ", 이전 글자 : " <<s[j-1] <<"\n"; 
                arr[s[j]-97]++;
                if(arr[s[j]-97] > 1) {
                    cout <<"중복된 글자 : " <<s[j] <<"\n";
                    isGroupWord = false;
                    break;
                }
            }
        }
        cout <<"문자 하나 체크 완료, ans 값 : "<< ans<< "\n";
        if(isGroupWord) {
            cout << "isGroupWord true 이므로 ans 증가 \n";
            ans++;
        }
        isGroupWord = true; //값 초기화
    }
    cout << ans;
    return 0;
}

 

 

 

 

 

반응형
반응형

 

문제 요약

알파벳으로 이루어진 입력 문자열에서 가장 많이 사용된 알파벳 대문자로 출력

가장 많이 사용된 알파벳이 2개 이상이라면 물음표 ? 출력

 

풀이 과정

알파벳 대문자(A~Z)는 아스키코드 65부터 90까지이며

알파벳 소문자(a~z)는 아스키코드 97부터 122까지이다

 

위의 두가지를 사용해서 처음에는 알파벳 a부터 z까지 해당하는 배열을 만들려고했으나

돌면서 중복 값을 찾는게 귀찮아서 벡터로 전환해서 해결했다

 

 

인덱스와 값으로 알파벳에 접근가능한 배열

A B C D E F G H I J K L M N O P W R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

아스키코드 65가 A이므로

index가 0인 경우, 65를 더한 다음 char 화하여 출력해주면 A가 출력이 되는 방법을 사용했다

 

초기값을 -1로 세팅해서 입력 문자열 str에 특정 알파벳이 나올 때마다

65나 97을 뺀 값을 벡터의 인덱스로 사용하여 증감연산자로 값을 1씩 올려준다

 

이때, 최대값을 저장하는 max와 최대값의 위치를 저장하는 index도 함께 업데이트를 해준다

 

문자열에서 반복되는 알파벳을 모두 체크한 다음 count를 사용하여 벡터에서 특정 max 값의 갯수를 센다

max의 값이 2개 이상이라면 물음표를 출력하고

그렇지 않는 경우에는 index에 65를 더하여 문자로 출력시켜주면 끝

 

 

코드

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

int main() {
	vector<int> v1(26,0);
	string str;
	cin >> str;
	
	int tmp = 0;
    
	int index = 0;    
	int max = -1;
    
	for(int i=0; i<str.length(); i++){
    		//소문자
    		if(97 <= str[i] && str[i] <=122) {
			v1[str[i] - 97]++;
			if(max < v1[str[i] - 97]){
				max = v1[str[i]-97];
				index = str[i]-97;
			}
		}
        	//대문자
        	else if(65 <= str[i] && str[i] <= 90){
			v1[str[i] - 65]++;
			if(max < v1[str[i] - 65]){
				max = v1[str[i]-65];
				index = str[i]-65;
			}
		}
	}
    
	int cnt = count(v1.begin(), v1.end(), max);
	if(2<=cnt) cout << "?";
	else cout << char(index + 65);
	return 0;
}

 

 

 

 

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

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net

 

반응형
반응형

문자열 반복해서 새로운 문자열을 만드는 문제

문제만보면 되게 쉬워보이는데 이전에 제출한게 틀려있길래 간만에 겸사겸사 풀어봄

 

 

 

 

 

 

 

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

//횟수만큼 반복해서 새로운 문자열 만들어주는 함수
int makeStr(int cnt, string str){
	//한번씩 출력할 문자열
	string tmpStr;
	
	for(int i=0; i<str.length(); i++){
		for(int j=0; j<cnt; j++){
			tmpStr += str[i];
		}
	}
	cout << tmpStr;
	return 0;
}

int main() {
	//전체 반복 횟수
	int totalCnt = 0;
	cin >> totalCnt;
	
    //makeStr 함수 호출 시 사용되는 변수 (횟수와 문자열)
	int tmpCnt = 0;    
	string tmpStr;
    
	for(int i=0; i<totalCnt; i++){
		cin >> tmpCnt;
		cin >> tmpStr;
		if(i>0) cout << "\n";
        //첫번째 입력이면 한번 출력 후 new line 필요없으므로
        //출력이 1이상일때부터 출력하도록 함
		makeStr(tmpCnt, tmpStr);
	}	
	return 0;
}

 

 

처음에 풀때는 메인함수에서 입력을 다 처리해주다가

그냥 문자열을 새로 만들어주는 함수 makeStr을 작성해서 호출하도록 했다

 

문자열 특성 상 배열처럼 인덱스 접근이 가능하므로

새로 만들 임시 문자열 tmpStr에 할당 연산자(+=)로 반복해야 하는 횟수만큼

i번째 문자열을 j(=cnt)번만큼 더해주었다

 

 

 

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

 

 

2675번: 문자열 반복

문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 P를 만든 후 출력하는 프로그램을 작성하시오. 즉, 첫 번째 문자를 R번 반복하고, 두 번째 문자를 R번 반복하는 식으로 P를 만들면 된다

www.acmicpc.net

 

반응형
반응형

 

 

하나라도 완료를 뜨게하고싶어서 시도한 입출력문제

new line(\n)과 문자열 escape(\)를 추가해주면 간단하게 해결할수있다

 

 

 

 

#include<bits/stdc++.h>
using namespace std;
int main() {	
	cout<<"\\    /\\\n )  ( ')\n(  /  )\n \\(__)|";
	return 0;
}

예제 출력을 그대로 복사 붙여넣기한 다음,

줄바꿈이 필요한 곳은 \n를 백슬래시(\)앞에는 \를 추가해주면 된다

 

 

 

#include<bits/stdc++.h>
using namespace std;
int main() {	
	cout<<"|\\_/|\n|q p|   /}\n( 0 )\"\"\"\\\n|\"^\"`    |\n||_/=\\\\__|";
	return 0;
}

 

 

 

 

이게 왜 개랑 고양이인가 싶었는데

막상 출력해보니 은근 귀여움ㅋ

 

 

 

반응형
반응형

 

 

 

 

 

입력된 문자열 2개를 같은 문자열로 만들기 위해 제거해야할 최소의 문자의 수를 구하는문제

 

예제를 보면 aabbcc와 xxyybb는 공통된 bb만을 갖고있으므로 나머지 aacc와 xxyy는 제거되어야한다

따라서 총 8개의 문자를 제거해야하므로 출력값은 8이 나오는것

 

 

풀이를 위해 생각한 과정

 

문자열 str1, str2를 각각 입력받은 다음, a부터 z까지의 크기를 갖는 배열 arr1, arr2를 만든다

 

str1에서 나온 문자를 arr1의 알파벳 문자에 해당하는 인덱스 값을 증가시켜주어

str1에 해당하는 문자의 개수를 기록한다

 

그렇게 str2도 동일한 과정을 거쳐

arr1과 arr2와의 차이를 모두 더한 값을 출력하도록했다

 

이때, 차이는 음수가 될수있으므로 음수인경우는 -부호를 붙여 양수로 만들어 계산을 했다

 

 

문제 - str1과 str2의 사이즈가 다르다는 생각을 못해서 런타임 에러가 났다

OutOfBounds 컨테이너 또는 배열에서 할당된 경계를 넘어가는 접근 발생

 

런타임 에러가 났길래 자세히 봤더니 배열 범위에 문제가 생긴듯해서 처음에는 알파벳개수에 문제가 생긴줄알았는데

입력받는 문자열의 개수가 다를수있다는걸 간과해서

 

각각의 개수를 반복하는 반복문으로 수정해서 오류 해결완료함

 

 

 

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

int main() {	
	string str1;
	string str2;	
	cin >> str1;
	cin >> str2;
	
	int arr1[27]={0};
	int arr2[27]={0};
	
	for(int i=0; i<str1.size();i++){		
		arr1[str1[i]-'a']++;	
	}
    
	for(int i=0; i<str2.size();i++){		
		arr2[str2[i]-'a']++;
	}
    
	int ans=0;
	int tmp;
	
	for(int i=0; i<26; i++){
		tmp = arr1[i]-arr2[i];		
		if(tmp >0){
			ans+=tmp;
		}else{
			ans+=(-tmp);
		}
	}
	cout << ans;
	return 0;
}

 

 

 

 

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

 

1919번: 애너그램 만들기

두 영어 단어가 철자의 순서를 뒤바꾸어 같아질 수 있을 때, 그러한 두 단어를 서로 애너그램 관계에 있다고 한다. 예를 들면 occurs 라는 영어 단어와 succor 는 서로 애너그램 관계에 있는데, occurs

www.acmicpc.net

 

반응형
반응형

백준 1475번 문제

 

 

 

 

별것아닌것같은데 헤매서 힘든문제였다

 

방번호를 0~9까지의 숫자 세트를 이용해서 만드는 문제로

6과 9는 각각 뒤집어서 사용할 수 있다

 

 

9999의 경우 숫자세트 4개가 필요한게 아니라, 9와 6 1세트, 9와 6 1세트 해서 총 2가 출력되면 된다

 

 

 

#include<bits/stdc++.h>
using namespace std;
 
int main() {
	string str;
	cin >> str;
 
	int arr[10]={0};
	int tmp;
	for(int i=0; i<str.size();i++){
		tmp = str[i]-'0';
		if(tmp ==9) {
			arr[6]++;
		}
		else{
			arr[tmp]++;
		}
	}
 
	int max = 1;
	
	if(arr[6] % 2==0){
		arr[6] = ceil(arr[6]/2);	
	}else{
		arr[6] = ceil(arr[6]/2)+1;
	}
	
	for(int i=0; i<9; i++){
		if(max < arr[i]){
			max = arr[i];
		}
	}
 
	cout << max;
 
	return 0;
}

 

숫자를 입력받으면 10으로 나눠주는걸 반복해야되니까

문자열로 받은 다음 하나 하나 쪼개서 숫자로 바꿔 배열에 삽입해주었다

 

그리고, 0부터 9까지의 int형 배열을 만들고 입력받은 숫자에 해당하는 배열 인덱스를 증가시켜줬다

그렇게 마지막에는 배열내의 가장 큰 값을 출력해주면 완성

 

 

 

+ 6과 9의 값은 하나로 합쳐서 관리하는게 편해서 배열을 0부터8까지만 들어가게끔 만들었다

 따라서 arr[6]의 값은 반으로 나누는 과정이 필요하다

 

+ 근데 소수점자리를 올려주는 ceil 함수는 그리 호락호락하지않았다

  (정수로 반환 해주지않아서 2.5가 계속 2로 나오는 바람에 arr[6]의 값을 홀수 짝수 나눠서 계산했다)

 

 

0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0

 

 

9999의 경우 배열 예시

0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 4 0 0

 

입력한 숫자에 해당하는 인덱스의 값을 모두 올려주고 난 다음에는

 

arr[6]의 값을 반으로 나누어주고

arr 배열에서 가장 큰 값을 출력해주도록 했다

 

 

 

 

문자를 정수로 변환하는법 참고 (char to int)

 

 

 

 

 

 

 

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

 

1475번: 방 번호

첫째 줄에 다솜이의 방 번호 N이 주어진다. N은 1,000,000보다 작거나 같은 자연수 또는 0이다.

www.acmicpc.net

 

https://stackoverflow.com/questions/1253670/why-do-round-and-ceil-not-return-an-integer

 

Why do round() and ceil() not return an integer?

Once in a while, I find myself rounding some numbers, and I always have to cast the result to an integer: int rounded = (int) floor(value); Why do all rounding functions (ceil(), floor()) return a

stackoverflow.com

 

 

반응형
반응형

 

 

 

문자열로 바꿔서 풀려다가 char를 정수형으로 바꾸는 atoi 사용법을 까먹어서

입력받은 숫자를 10으로 나눈 몫과 나머지를 반복사용해서 풀고싶었는데

이 방식은 입력받는 수의 범위때문인지 답이없어서 그냥 문자열을 int형변환 하는법을 다시 검색해서 수정함

 

 

스택오버플로우는 언제나 좋은 친구

 

간단한 문자-정수 형변환

아스키코드의 숫자는 48부터 시작하여 int로 형변환 후 48을 빼주어야 정확한 값을 얻을수있다

(아스키에서는 0=48이란 소리)

 

다른 방법으로는 문자 자체에서 아예 48을 빼주는 방법이 있다

 

 

 

위의 방법을 이용하여

두번째에 입력받은 수인 input을 아예 string으로 입력받은 다음 하나하나 정수로 바꿔서 더했다

 

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

int main() {
	int cnt;
	string input;
	
	cin >>cnt;
	cin >> input;
	
	int ans=0;
	char c;
	int tmp;
	for(int i=0; i<cnt; i++){
		c= input[i];
		tmp =(int)c-48;
		ans+=tmp;
	}
	cout << ans;
	return 0;
}

 

 

문자열 대신 char형 배열을 이용한 다른 방법

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

int main() {
	int cnt;
	char c[101];
	cin >>cnt;
	
	int ans=0;
	
	for(int i=0; i<cnt; i++){
		cin >> c[i];
		ans+=(int)c[i]-48;
	}
	
	cout << ans;
	return 0;
}

 

 

출처 : www.acmicpc.net/problem/11720

 

11720번: 숫자의 합

첫째 줄에 숫자의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄에 숫자 N개가 공백없이 주어진다.

www.acmicpc.net

참고사이트 : stackoverflow.com/questions/5029840/convert-char-to-int-in-c-and-c

 

Convert char to int in C and C++

How do I convert a char to an int in C and C++?

stackoverflow.com

 

반응형

+ Recent posts