Koder / 박성훈
article thumbnail

숫자범위 자비좀....

https://www.acmicpc.net/problem/2870

 

2870번: 수학숙제

종이에서 찾은 숫자의 개수를 M이라고 하면, 출력은 M줄로 이루어져야 한다. 각 줄에는 종이에서 찾은 숫자를 하나씩 출력해야 한다. 이때, 비내림차순으로 출력해야 한다. 비내림차순은 내림차

www.acmicpc.net

일단 문제 지문에서 유추해내야 하는 조건으로써

나오는 숫자의 길이가 매우 길어져서

int 및 long long 으로 저장할 수 없는 경우가 있다.

 

따라서 숫자를 다룰생각을하지를 말고 문자열로 다뤄줘야 하는 문제.

문자열을 가지고 놀기 위해서 몇몇가지 함수를 짜줬다.

 

1. bool isalpha(char c)

들어온 글자 한글자가 영문자인지 체크하는 함수.

bool isalpha(char c){
	return 'a' <= c && c <= 'z';
}

 

2. string cut(string a)

들어온 문자열 앞부분에 있는 불필요한 0을 제거.

플래그 변수를 하나 만들어서 앞부분부터 읽다가 0이 아닌 숫자를 발견하면

그 부분부터 문자열을 잘라내서 반환한다.

 

들어오는 문자열이 "000000" 인 경우가 있는데,

이 경우에는 "0" 을 따로 반환하게 작성해줘야함에 유의

string cut(string a){
	bool flag = false;
	string ret = "";
	for(int i=0; i<a.length(); i++){
		if(a[i] != '0') flag = true;
		if(flag){
			ret += a[i];
		}
	}
	if(ret == "") return "0";
	return ret;
}

 

이 두 함수를 만든 뒤에,

입력받은 문자열에서 연속된 숫자로 이루어진 부분을 잘라서 cut() 에 넘겨주면

출력하고자 하는 숫자들을 얻을 수 있다.

이 숫자들을 vector에 넣고, 문제에서 요구하는 우선순위대로 정렬해서 출력해주면 AC를 받을 수 있다.

 

문자열다루기가 실수하기가 쉽다 보니 몇번 WA를 받았던 문제.

 

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

vector<string> ans;

bool isalpha(char c){
	return 'a' <= c && c <= 'z';
}

bool cmp(const string &a, const string &b){
	if(a.length() == b.length()) return a<b;
	return a.length() < b.length();
}

string cut(string a){
	bool flag = false;
	string ret = "";
	for(int i=0; i<a.length(); i++){
		if(a[i] != '0') flag = true;
		if(flag){
			ret += a[i];
		}
	}
	if(ret == "") return "0";
	return ret;
}

int main(){
	int N;
	string s;
	
	cin >> N;
	for(int i=0; i<N; i++){
		cin >> s;
		string var;
		
		for(int j=0; j<s.length(); j++){
			if(isalpha(s[j])){
				if(!j || isalpha(s[j-1])) continue;
				ans.push_back(cut(var));
				var = "";
			}
			else{
				var += s[j];
			}
		}
		if(var != "") ans.push_back(cut(var));
	}
	
	sort(ans.begin(), ans.end(), cmp);
	for(auto k : ans){ cout << k << "\n"; }
	return 0;
}

반응형