오토마타로 해결한다는 힌트를 듣고 오토마타가 뭔지 찾아서 문제의 오토마타를 나름대로 그려보았다.
얼추 되는 거 같지만 10001100001 와 같은 예는 식별하지 못한다.
그래서 100+ 이후의 1+ 에 대해서 상태를 추가해서 좀더 세밀하게 만들었다.
오토마타를 처음 접했는데, 뭔가 그래프의 인접행렬과 유사한 느낌인 것 같아서 새로웠다.
위의 그림은 노트에 끄적거린 것을 그대로 옮긴거라 좀 정리가 안되어있다.
처음에는 7번 상태 없이, 5번 상태에서 1인 경우 다시 5번으로 돌아와 1+ 를 나타내려 했는 데 엉망이였다. 1이 조금만 반복해도 맞다고 되어버렸다.
1+ 의 형태를 반복하다가 0 이 나오면 새로운 100+ 패턴인지 01 로 끊어지는 패턴인지 구분할 수 있도록 7번 상태를 추가했더니 잘 돌아갔다.
빨간색 화살표는 식별을 못하는 FAIL 상태이고, 초록색 상태는 패턴이 올바르게 끝난 상태이다.
동일한 문제
#include <cstdio> #define ROOT 0 #define FAIL 8 int jump[9][2]={ // [0] 일 때 가는 경우, [1] 일 때 가는 경우 {1, 2}, {FAIL, ROOT}, // -0 {4, FAIL}, // -1 {6, ROOT}, // 1001-1001 의 구분점 {6, FAIL}, // -10- {1, 7}, // 100-1 {6, 5}, // -100+ {3, 7}, // -1+ {FAIL, FAIL} }; bool isRight(int pos){ return (pos == ROOT || pos == 5 || pos == 7); } int main(){ int i, j, n; char s[205]={}; while(~scanf("%s ", s)){ int curPos = ROOT; for(i=0; s[i]; ++i){ curPos = jump[curPos][s[i]-'0']; if(curPos == FAIL) break; } puts(isRight(curPos)?"SUBMARINE":"NOISE"); } return 0; }
댓글 없음:
댓글 쓰기