2022. 10. 21. 00:54ㆍ알고리즘/코딩테스트(백준)
코드 복사해서 반례를 찾아주시는 분께 선물 드리겠습니다(진짜임).
문제
좋은 패스워드를 만드는것은 어려운 일이다. 대부분의 사용자들은 buddy처럼 발음하기 좋고 기억하기 쉬운 패스워드를 원하나, 이런 패스워드들은 보안의 문제가 발생한다. 어떤 사이트들은 xvtpzyo 같은 비밀번호를 무작위로 부여해 주기도 하지만, 사용자들은 이를 외우는데 어려움을 느끼고 심지어는 포스트잇에 적어 컴퓨터에 붙여놓는다. 가장 이상적인 해결법은 '발음이 가능한' 패스워드를 만드는 것으로 적당히 외우기 쉬우면서도 안전하게 계정을 지킬 수 있다.
회사 FnordCom은 그런 패스워드 생성기를 만들려고 계획중이다. 당신은 그 회사 품질 관리 부서의 직원으로 생성기를 테스트해보고 생성되는 패스워드의 품질을 평가하여야 한다. 높은 품질을 가진 비밀번호의 조건은 다음과 같다.
- 모음(a,e,i,o,u) 하나를 반드시 포함하여야 한다.
- 모음이 3개 혹은 자음이 3개 연속으로 오면 안 된다.
- 같은 글자가 연속적으로 두번 오면 안되나, ee 와 oo는 허용한다.
이 규칙은 완벽하지 않다;우리에게 친숙하거나 발음이 쉬운 단어 중에서도 품질이 낮게 평가되는 경우가 많이 있다.
입력
입력은 여러개의 테스트 케이스로 이루어져 있다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 테스트할 패스워드가 주어진다.
마지막 테스트 케이스는 end이며, 패스워드는 한글자 이상 20글자 이하의 문자열이다. 또한 패스워드는 대문자를 포함하지 않는다.
출력
각 테스트 케이스를 '예제 출력'의 형태에 기반하여 품질을 평가하여라.
https://www.acmicpc.net/problem/4659
딱히 풀이라고 할게 없는 문제다..
조건 3가지
- 모음(a,e,i,o,u) 하나를 반드시 포함하여야 한다.
- 모음이 3개 혹은 자음이 3개 연속으로 오면 안 된다.
- 같은 글자가 연속적으로 두번 오면 안되나, ee 와 oo는 허용한다
를 빡구현 하면 되겠다.
package com.company.string;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public class No4659 {
static StringBuilder sb;
static String good = "is acceptable.";
static String bad = "is not acceptable.";
static List<Character> vowel = Arrays.asList('a', 'e', 'i', 'o', 'u');
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
sb = new StringBuilder();
while (true) {
String s = br.readLine();
//end를 입력받는 경우 종료.
if (s.equals("end")) {
break;
}
//입력받은 문자열이 한 글자인 경우
//모음이면 acceptable, 자음이면 not acceptable
if (s.length() == 1) {
if(vowel.contains(s.charAt(0))) {
sb.append("<" + s + "> " + good).append('\n');
}else{
sb.append("<" + s + "> " + bad).append('\n');
}
continue;
}
//만약 3가지 조건 중 하나라도 만족하지 못하면 acceptable을 false로 변경한다.
//acceptable이 마지막까지 true라면 acceptable을 출력한다.
boolean acceptable = true;
//조건 1. 모음이 반드시 하나 이상 있어야 한다.
//하나라도 모음이 있다면 vowelFlag는 true
boolean vowelFlag = false;
//조건 2. 모음 3개 또는 자음 3개가 연속으로 오면 안된다.
//자음인 경우 true, 모음인 경우 false
boolean flag = true;
// 만약 앞글자와 자-모음이 동일하다면 count ++, 다르다면 count = 1 초기화
// count가 3이 되는 순간 not acceptable을 출력한다.
int count = 1;
// 문자열의 첫 번째 글자
char c = s.charAt(0);
//첫 번째 글자가 모음인 경우
if(vowel.contains(c)) {
//모음인 경우 조건 1 통과
vowelFlag = true;
//모음
flag = false;
}
for (int i = 1; i < s.length(); i++) {
for (int j = 0; j < 5; j++) {
//조건 1 검사: 모음을 반드시 하나 이상 포함해야 한다.
if(vowel.contains(s.charAt(i))){
vowelFlag = true;
break;
}
}
// 조건 1 검사: 모음이 없는 문자열인 경우 not acceptable 출력
if(!vowelFlag){
sb.append("<" + s + "> " + bad).append('\n');
acceptable = false;
break;
}
//조건 3. 같은 글자가 연속적으로 두번 오면 안되나, ee 와 oo는 허용한다
//앞 글자와 현재 i번째 글자가 동일한 경우
if(s.charAt(i) == c){
//'e', 'o'는 허용한다.
if(c == 'e' || c == 'o'){
}
//조건 3 검사: 'e', 'o'가 아니라면 not acceptable 출력
else{
sb.append("<" + s + "> " + bad).append('\n');
acceptable = false;
break;
}
}else{
//앞 글자와 다른 경우, 앞 글자를 현재 i번째 글자로 변경한 뒤 넘어간다.
c = s.charAt(i);
}
//조건 2. 모음 3개 또는 자음 3개가 연속으로 오면 안된다.
//flag 경우 --> 앞 글자가 자음인 경우
//!flag 경우 --> 앞 글자가 모음
if (flag) {
//앞 글자가 자음인 경우
//현재 글자가 모음이라면, flag를 false로 변경하고, count를 1로 초기화한다.
if(vowel.contains(s.charAt(i))){
flag = false;
count = 1;
//만약 앞글자와 마찬가지로 자음이라면, count를 1 늘린다.
//근데 count가 3이라면 자-모음이 3연속 등장한 것이므로 not acceptable을 출력해야 한다.
}else{
count ++;
if (count == 3) {
sb.append("<" + s + "> " + bad).append('\n');
acceptable = false;
break;
}
}
//앞 글자가 모음인 경우
}else{
//현재 글자가 똑같이 모음이라면 count를 1 늘린다.
//count가 3이라면 not acceptable을 출력해야 한다.
if (vowel.contains(s.charAt(i))) {
count++;
if (count == 3) {
sb.append("<" + s + "> " + bad).append('\n');
acceptable = false;
break;
}
//현재 글자가 자음인 경우
//flag를 true로 초기화 하고 count도 1로 초기화한다.
}else{
flag = true;
count = 1;
}
}
}
//acceptable인 경우 출력
if(acceptable)
sb.append("<" + s + "> " + good).append('\n');
}
System.out.println(sb);
}
}
엄청 길고 지저분하게 코드를 작성했더니
역시나 오답이 나왔다!!
반례가 너무너무 궁금하다.
백준 질문 커뮤니티에 있는 반례들은 전부 다 통과했다만
'알고리즘 > 코딩테스트(백준)' 카테고리의 다른 글
백준 1495: 기타리스트 (0) | 2022.10.22 |
---|---|
백준 2941: 크로아티아 알파벳 [Java] - 포포 // 반례 有 (0) | 2022.10.21 |
백준 1238: 파티 [Java] - 포포 (1) | 2022.09.11 |
백준 1463: 1로 만들기 [Java] -포포 (0) | 2022.09.01 |
백준 2143: 두 배열의 합[Java] - 포포 (0) | 2022.08.02 |