#include <cstdio>#include <string>#include <cstring>#include <cmath>usingnamespacestd;intn,m,q;// 분류기가 반환한 문장. 단어 번호로 변환되어 있음intR[100];// T[i][j] = i 단어 이후에 j 단어가 나올 확률의 로그값doubleT[501][501];// M[i][j] = i 단어가 j 단어로 분류될 확률의 로그값doubleM[501][501];intchoice[102][102];doublecache[102][502];// 1로 초기화한다.// Q[segment] 이후를 채워서 얻을 수 있는 최대 g() 곱의 로그값을 반환한다.// Q[segment-1] == previousMatch라고 가정한다.doublerecognize(intsegment,intpreviousMatch){if(segment==n)return0;double&ret=cache[segment][previousMatch];if(ret!=1.0)returnret;ret=-1e200;// log(0) = 음의 무한대에 해당하는 값int&choose=choice[segment][previousMatch];// R[segment]에 대응되는 단어를 찾는다.for(intthisMatch=1;thisMatch<=m;thisMatch++){// g(thisMatch) = T(previousMatch, thisMatch) * M(thisMatch, R[segment])doublecand=T[previousMatch][thisMatch]+M[thisMatch][R[segment]]+recognize(segment+1,thisMatch);if(ret<cand){ret=cand;choose=thisMatch;}}returnret;}// 입력받은 단어들의 목록stringcorpus[501];stringreconstruct(intsegment,intpreviousMatch){intchoose=choice[segment][previousMatch];stringret=corpus[choose];if(segment<n-1){ret=ret+" "+reconstruct(segment+1,choose);}returnret;}intmain(){doubleB[501];charinputWords[501][11],classifyWords[501][11];scanf("%d %d",&m,&q);for(inti=1;i<=m;i++){scanf("%s",inputWords[i]);}for(inti=1;i<=m;i++){scanf("%lf",&B[i]);B[i]=log(B[i]);}for(inti=0;i<=m;i++){for(intj=1;j<=m;j++){//책의 트릭을 이용하여 시작단어를 [0][j] 인덱스에 저장//즉, Q[0]가 항상 시작단어라고 지정//그렇게 하면 P(Q)=∏(T(Q[i-1], Q[i])) => Begin(Q[0])*∏(T(Q[i-1], Q[i]))보다 간단if(i==0)T[i][j]=B[j];else{scanf("%lf",&T[i][j]);T[i][j]=log(T[i][j]);}}}for(inti=1;i<=m;i++){for(intj=1;j<=m;j++){scanf("%lf",&M[i][j]);M[i][j]=log(M[i][j]);}}for(inti=1;i<=m;i++){corpus[i]=string(inputWords[i]);}while(q--){scanf("%d",&n);// double 타입은 memset으로 초기화하면 문제발생for(inti=0;i<n;i++){for(intj=0;j<=m;j++){cache[i][j]=1.0;}}memset(choice,-1,sizeof(choice));memset(R,-1,sizeof(R));for(inti=0;i<n;i++){scanf("%s",classifyWords[i]);for(intj=1;j<=m;j++){if(strcmp(classifyWords[i],inputWords[j])==0){R[i]=j;break;}}}recognize(0,0);printf("%s\n",reconstruct(0,0).c_str());}return0;}
5년 전
0개의 댓글이 있습니다.
정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면
온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야
합니다. 현재 문제를 푸셨습니다.
ccinoLee
안녕하세요.
OCR 문제와 관련하여, 오답처리 부분이 있어서 질문드립니다.
책의 소스코드와 인터넷 검색을 통해 예제 입력/출력은 해결하였습니다.
그런데 소스코드를 제출하면 계속 오답으로 뜨는 문제가 있는데 무엇이 문제일지 감이 안잡히네요.. 그럼 확인 부탁드립니다
문제정보
OCR
연습 문제
소스코드
5년 전