9996번: 한국이 그리울 땐 서버에 접속하지
- 요약하자면 첫 입력으로 입력 횟수가 주어지고 두 번째 입력으로 패턴이 주어짐
- 패턴은 a*b 와 같은 식으로 되어 있는데
- 이후 입력 횟수에 따라 입력되는 문장들이 패턴에 부합하는지 체크해서 부합하면 DA, 아니면 NE를 출력하는 문제
먼저 무작정 풀어보기
#include <iostream>
#include <vector>
#include <string>
int main()
{
int n = 0;
std::cin >> n;
std::string patt;
std::cin >> patt;
std::string temp;
std::vector<std::string> res;
for (int i = 0; i < n; i++)
{
std::cin >> temp;
if (temp.front() == patt.front() &&
temp.back() == patt.back())
res.push_back("DA");
else
res.push_back("NE");
}
for (int i = 0; i < res.size(); i++)
{
if (i == res.size() - 1){
std::cout << res[i];
break;
}
std::cout << res[i] << std::endl;
}
}
- 맞왜틀(맞는데 왜 틀림)이 많이 나왔던 문제
- 상식이라고 생각했던 부분들에 뒤통수를 쎄게 맞았다.
- 입력 예문에서 a*b라고 되어 있길래 * 문자 앞 뒤로 한 글자만 오는 줄 착각했던 게 화근이었다.
- 맨 위는 와일드카드 앞 뒤로 한 글자만 오는 게 아니라는 생각이 문득 들어서 2차시도 한 흔적이다.
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> split(std::string text, std::string delimiter)
{
std::string temp;
int offset = 0;
std::vector<std::string> ret;
while ((offset = text.find(delimiter, 0)) != std::string::npos)
{
temp = text.substr(0, offset);
ret.push_back(temp);
text.erase(0, offset + delimiter.length());
}
ret.push_back(text);
return ret;
}
int main()
{
int n = 0;
std::cin >> n;
std::string patt;
std::cin >> patt;
std::vector<std::string> words = split(patt, "*");
std::string temp;
std::vector<std::string> res;
for (int i = 0; i < n; i++)
{
std::cin >> temp;
if (words[0] == temp.substr(0, words[0].size()) &&
words[1] == temp.substr(temp.size() - words[1].size()))
res.push_back("DA");
else
res.push_back("NE");
}
for (auto& s : res)
std::cout << s << std::endl;
}
- 2차 시도 코드
- 2차 시도는 split 함수를 사용해서 와일드 카드를 기준으로 분할한 후 앞, 뒤 값을 확인하여 비교하도록 했다.
- 여기서는 런타임 에러가 떴다.(ㅡㅡ..)
- 이후 큰돌님의 강의를 보고 반례 체크를 해야 한다는 사실을 깨달았다.
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> split(std::string text, std::string delimiter)
{
std::string temp;
int offset = 0;
std::vector<std::string> ret;
while ((offset = text.find(delimiter, 0)) != std::string::npos)
{
temp = text.substr(0, offset);
ret.push_back(temp);
text.erase(0, offset + delimiter.length());
}
ret.push_back(text);
return ret;
}
int main()
{
int n = 0;
std::cin >> n;
std::string patt;
std::cin >> patt;
std::vector<std::string> words = split(patt, "*");
std::string temp;
std::vector<std::string> res;
for (int i = 0; i < n; i++)
{
std::cin >> temp;
// 반례 체크
if (temp.size() < words[0].size() + words[1].size())
res.push_back("NE");
else if (words[0] == temp.substr(0, words[0].size()) &&
words[1] == temp.substr(temp.size() - words[1].size()))
res.push_back("DA");
else
res.push_back("NE");
}
for (auto& s : res)
std::cout << s << std::endl;
}
- 반례를 체크하는 이유는 ab*ab라는 패턴이 주어졌을 때 ab 라는 문장이 맞다는게 되기 때문
- 앞으로는 쉬운 문제라도 논리적으로 말이 되는지 생각하는 습관을 들여야겠다.
- 반례를 구하니 통과처리되었다.
큰돌님의 풀이
#include <iostream>
#include <vector>
#include <string>
int n;
std::string s, ori_s, pre, suf;
int main()
{
std::cin >> n;
std::cin >> ori_s;
int pos = ori_s.find('*');
pre = ori_s.substr(0, pos);
suf = ori_s.substr(pos + 1);
for (int i = 0; i < n; i++)
{
std::cin >> s;
if (pre.size() + suf.size() > s.size()) {
std::cout << "NE\n";
}
else {
if (pre == s.substr(0, pre.size()) && suf == s.substr(s.size() - suf.size()))
std::cout << "DA\n";
else
std::cout << "NE\n";
}
}
return 0;
}
- split 대신 substr을 사용하셨다.
- substr을 통해 별 표 기준으로 앞 뒤만 자르는 방법을 왜 생각하지 못했을까
- 나 스스로 느끼기에 처음 생각했던 방향성에 갇혀 있는 경향이 좀 있는 것 같다.
'자료구조와 알고리즘 > [Inflearn_큰돌] 10주 완성 C++ 코딩테스트' 카테고리의 다른 글
3주차-완전탐색 (0) | 2024.10.21 |
---|---|
부록 : i, j로 이루어진 이중 for문 에서 j < i가 조건일 때 시간복잡도 계산 (0) | 2023.03.27 |
1주차-4. 11655번: ROT13 (1) | 2022.09.26 |
1주차-3. 1159번 농구 경기 (1) | 2022.09.26 |
1주차-2. 10988번 팰린드롬인지 확인하기 (2) | 2022.09.13 |
댓글