ZOJ - 4022 Honorifics (最大似然估计)

题目链接
这是我三年前打组队赛的时候见到的题,当时一点头绪都没,最近学了机器学习之后突然想起还有这么一个坑没有填,于是就试了下
第一次见到这种类型的题,题目很有创意,为出题人点赞(虽然不知道ML的题放在ACM里是否合适)
题目的意思是,给出一系列人名的罗马音表示,让你判断是日本人还是韩国人
题目给了训练数据,这个是原链接,新的链接失效了,估计是因为zoj搬到了pta上,然而训练数据没搬过去(感谢队友xz帮我找到原数据)
思路:
只考虑姓名的罗马音中相邻两字符之间的关系,定义矩阵a,a[i][j]表示字母i的下一个字母是j的概率,并新增两个虚拟结点S和T表示开头和结尾,通过矩阵预测姓名出现的概率,比如“Kami”出现的概率就是a[S][k]*a[k][a]*a[a][m]*a[m][i]*a[i][T]。矩阵a可以通过对训练数据统计获得,对两种人的姓名总共建四个矩阵。预测一个人的时候,先假设他是韩国人,对他的姓名分别求出出现的概率,然后累乘,然后再假设他是日本人,求出另一个概率,哪个概率大就把他判别为哪类。(但实际上计算的不是累乘,而是对数的累加,防止精度爆炸,这个东西貌似叫做对数似然)
训练代码:

 1 #define FRER() freopen("i.txt","r",stdin)
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef double db;
 5 const double inf=1e16,eps=1e-6;
 6 struct Model {
 7     static const int N=28;
 8     static const int S=26,T=27;
 9     db a[N][N];
10     int id(char c) {return tolower(c)-'a';}
11     void init() {memset(a,0,sizeof a);}
12     void add(string s) {
13         a[S][id(s[0])]+=1;
14         for(int i=0; i<(int)s.length()-1; ++i)a[id(s[i])][id(s[i+1])]+=1;
15         a[id(s[s.length()-1])][T]+=1;
16     }
17     void train() {
18         for(int i=0; i<N; ++i) {
19             db sum=0;
20             for(int j=0; j<N; ++j)sum+=a[i][j];
21             if(sum>eps)for(int j=0; j<N; ++j)a[i][j]/=sum;
22             for(int j=0; j<N; ++j)a[i][j]=a[i][j]>eps?log(a[i][j]):-inf;
23         }
24     }
25     db pred(string s) {
26         db ret=0;
27         ret+=a[S][id(s[0])];
28         for(int i=0; i<(int)s.length()-1; ++i)ret+=a[id(s[i])][id(s[i+1])];
29         ret+=a[id(s[s.length()-1])][T];
30         return ret;
31     }
32     void pr() {
33         printf("   ");
34         for(int i='a'; i<='z'; ++i)printf("%c    ",i);
35         puts("");
36         for(int i=0; i<N; ++i,puts("")) {
37             printf("%c",i+'a');
38             printf("  ");
39             for(int j=0; j<N; ++j)printf("%.2f ",a[i][j]);
40         }
41     }
42 } L[2],R[2];
43 int pred(string s1,string s2) {
44     db l[2];
45     for(int i=0; i<2; ++i)l[i]=L[i].pred(s1)+R[i].pred(s2);
46     return l[0]>l[1]?0:1;
47 }
48 struct Person {
49     string s1,s2;
50     int f;
51 };
52 vector<Person> vec;
53 int main() {
54     //FRER();
55     for(int i=0; i<2; ++i)L[i].init(),R[i].init();
56     string s1,s2;
57     int f;
58     while(cin>>s1>>s2) {
59         f=s2[s2.length()-2]=='a'?1:0;
60         s2=s2.substr(0,s2.length()-4);
61         vec.push_back({s1,s2,f});
62     }
63     for(int i=0; i<6000; ++i) {
64         const Person& p=vec[i];
65         s1=p.s1,s2=p.s2,f=p.f;
66         L[f].add(s1);
67         R[f].add(s2);
68     }
69     for(int i=0; i<2; ++i)L[i].train(),R[i].train();
70     return 0;
71 }
View Code

提交代码:

  1 #define FRER() freopen("i.txt","r",stdin)
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 typedef double db;
  5 const db inf=1e16,eps=1e-6;
  6 const db a[]= {
  7     0.000,0.000,0.000,0.000,0.190,0.000,0.016,0.000,0.000,0.000,0.086,0.024,0.086,0.426,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.172,
  8     0.515,0.000,0.000,0.000,0.172,0.000,0.000,0.000,0.162,0.000,0.000,0.000,0.000,0.000,0.096,0.000,0.000,0.000,0.000,0.000,0.056,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
  9     0.000,0.000,0.000,0.000,0.000,0.000,0.000,1.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 10     0.429,0.000,0.000,0.000,0.092,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.424,0.000,0.000,0.000,0.000,0.000,0.054,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 11     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.027,0.000,0.000,0.025,0.567,0.000,0.000,0.000,0.000,0.000,0.146,0.000,0.000,0.000,0.000,0.000,0.000,0.235,
 12     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 13     0.060,0.046,0.000,0.000,0.041,0.000,0.000,0.000,0.034,0.039,0.000,0.000,0.023,0.000,0.053,0.000,0.000,0.000,0.000,0.000,0.025,0.000,0.054,0.000,0.044,0.000,0.000,0.580,
 14     0.293,0.000,0.000,0.000,0.052,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.262,0.000,0.000,0.000,0.000,0.000,0.138,0.000,0.200,0.000,0.055,0.000,0.000,0.000,
 15     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.029,0.238,0.448,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.285,
 16     0.181,0.000,0.000,0.000,0.569,0.000,0.000,0.000,0.069,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.181,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 17     0.000,0.000,0.000,0.000,0.000,0.000,0.046,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.037,0.000,0.000,0.000,0.000,0.917,
 18     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,1.000,
 19     0.153,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.069,0.000,0.000,0.000,0.000,0.000,0.136,0.000,0.000,0.000,0.000,0.000,0.146,0.000,0.000,0.000,0.074,0.000,0.000,0.422,
 20     0.027,0.000,0.000,0.000,0.000,0.000,0.557,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.025,0.000,0.000,0.000,0.000,0.000,0.031,0.000,0.000,0.000,0.000,0.000,0.000,0.360,
 21     0.000,0.000,0.000,0.000,0.045,0.000,0.013,0.000,0.000,0.000,0.101,0.017,0.063,0.454,0.000,0.015,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.292,
 22     0.123,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.180,0.000,0.000,0.000,0.000,0.000,0.123,0.000,0.000,0.000,0.352,0.000,0.000,0.221,
 23     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 24     0.579,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.158,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.263,0.000,0.000,0.000,
 25     0.155,0.000,0.000,0.000,0.456,0.000,0.000,0.000,0.150,0.000,0.000,0.000,0.000,0.000,0.102,0.000,0.000,0.000,0.000,0.000,0.137,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 26     1.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 27     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.122,0.000,0.069,0.378,0.000,0.038,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.393,
 28     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 29     0.809,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.191,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 30     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 31     0.035,0.000,0.000,0.000,0.543,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.278,0.000,0.000,0.000,0.000,0.000,0.143,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 32     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 33     0.005,0.083,0.048,0.095,0.027,0.000,0.110,0.101,0.022,0.058,0.004,0.000,0.099,0.031,0.014,0.049,0.000,0.029,0.116,0.026,0.014,0.000,0.022,0.000,0.047,0.000,0.000,0.000,
 34     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 35     0.000,0.001,0.004,0.001,0.263,0.000,0.005,0.004,0.004,0.012,0.056,0.021,0.055,0.396,0.000,0.024,0.000,0.017,0.013,0.005,0.005,0.000,0.002,0.000,0.023,0.000,0.000,0.089,
 36     0.120,0.000,0.000,0.000,0.169,0.000,0.000,0.000,0.157,0.000,0.000,0.000,0.000,0.000,0.373,0.000,0.000,0.000,0.000,0.000,0.036,0.000,0.000,0.000,0.145,0.000,0.000,0.000,
 37     0.000,0.000,0.000,0.000,0.000,0.000,0.000,1.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 38     0.315,0.000,0.000,0.000,0.185,0.000,0.000,0.000,0.012,0.000,0.000,0.000,0.000,0.000,0.381,0.000,0.000,0.000,0.000,0.000,0.107,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 39     0.004,0.006,0.006,0.001,0.001,0.000,0.013,0.018,0.003,0.018,0.009,0.000,0.006,0.012,0.644,0.003,0.000,0.012,0.023,0.001,0.136,0.000,0.011,0.000,0.009,0.000,0.000,0.065,
 40     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 41     0.050,0.017,0.018,0.009,0.043,0.000,0.063,0.059,0.070,0.043,0.000,0.000,0.026,0.005,0.014,0.004,0.000,0.014,0.053,0.008,0.058,0.000,0.049,0.000,0.150,0.000,0.000,0.246,
 42     0.239,0.000,0.000,0.000,0.107,0.000,0.000,0.000,0.015,0.000,0.000,0.000,0.000,0.000,0.123,0.000,0.000,0.000,0.000,0.000,0.209,0.000,0.075,0.000,0.233,0.000,0.000,0.000,
 43     0.008,0.006,0.006,0.006,0.005,0.000,0.021,0.038,0.000,0.024,0.093,0.096,0.044,0.320,0.000,0.011,0.000,0.020,0.033,0.006,0.005,0.000,0.014,0.000,0.026,0.000,0.000,0.219,
 44     0.219,0.000,0.000,0.000,0.223,0.000,0.000,0.000,0.239,0.000,0.000,0.000,0.000,0.000,0.089,0.000,0.000,0.000,0.000,0.000,0.229,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 45     0.000,0.018,0.015,0.000,0.000,0.000,0.079,0.061,0.012,0.030,0.000,0.000,0.006,0.012,0.000,0.006,0.000,0.009,0.045,0.000,0.012,0.000,0.000,0.000,0.021,0.000,0.000,0.673,
 46     0.000,0.042,0.000,0.024,0.000,0.000,0.042,0.048,0.024,0.042,0.000,0.000,0.018,0.012,0.000,0.000,0.000,0.012,0.024,0.000,0.006,0.000,0.000,0.000,0.012,0.000,0.000,0.693,
 47     0.101,0.003,0.018,0.009,0.009,0.000,0.028,0.009,0.252,0.031,0.000,0.000,0.000,0.000,0.040,0.000,0.000,0.000,0.028,0.000,0.141,0.000,0.000,0.000,0.150,0.000,0.000,0.181,
 48     0.034,0.010,0.010,0.007,0.004,0.000,0.512,0.039,0.008,0.019,0.000,0.000,0.007,0.004,0.007,0.009,0.000,0.003,0.039,0.002,0.007,0.000,0.000,0.000,0.012,0.000,0.000,0.268,
 49     0.002,0.001,0.001,0.000,0.008,0.000,0.008,0.010,0.000,0.011,0.096,0.044,0.034,0.636,0.000,0.019,0.000,0.008,0.014,0.000,0.000,0.000,0.003,0.000,0.007,0.000,0.000,0.097,
 50     0.116,0.000,0.000,0.000,0.000,0.000,0.032,0.000,0.053,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.032,0.053,0.000,0.011,0.000,0.000,0.000,0.284,0.000,0.000,0.421,
 51     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 52     0.300,0.000,0.000,0.000,0.067,0.000,0.000,0.000,0.258,0.000,0.000,0.000,0.000,0.000,0.058,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.317,0.000,0.000,0.000,
 53     0.122,0.000,0.000,0.000,0.486,0.000,0.000,0.000,0.141,0.000,0.000,0.000,0.000,0.000,0.058,0.000,0.000,0.000,0.000,0.000,0.193,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 54     0.787,0.000,0.000,0.000,0.000,0.000,0.043,0.000,0.021,0.000,0.000,0.000,0.000,0.000,0.064,0.000,0.000,0.000,0.000,0.000,0.043,0.000,0.000,0.000,0.000,0.000,0.000,0.043,
 55     0.002,0.008,0.003,0.002,0.001,0.000,0.012,0.022,0.093,0.011,0.078,0.024,0.006,0.458,0.002,0.000,0.000,0.024,0.034,0.001,0.000,0.000,0.001,0.000,0.008,0.000,0.000,0.209,
 56     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 57     0.577,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.077,0.000,0.000,0.000,0.000,0.000,0.346,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 58     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 59     0.025,0.000,0.000,0.000,0.664,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.148,0.000,0.000,0.000,0.000,0.000,0.163,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 60     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 61     0.005,0.044,0.040,0.065,0.023,0.000,0.109,0.121,0.033,0.149,0.001,0.000,0.069,0.025,0.006,0.005,0.000,0.005,0.174,0.012,0.020,0.000,0.016,0.000,0.079,0.000,0.000,0.000,
 62     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 63     0.000,0.010,0.000,0.023,0.005,0.000,0.046,0.014,0.028,0.000,0.096,0.000,0.075,0.049,0.007,0.000,0.000,0.056,0.043,0.061,0.000,0.000,0.070,0.000,0.021,0.020,0.000,0.375,
 64     0.612,0.000,0.000,0.000,0.212,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.129,0.000,0.000,0.000,0.000,0.000,0.047,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 65     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 66     0.772,0.000,0.000,0.000,0.046,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.143,0.000,0.000,0.000,0.000,0.000,0.039,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 67     0.000,0.000,0.000,0.145,0.000,0.000,0.094,0.027,0.043,0.000,0.067,0.000,0.067,0.106,0.000,0.000,0.000,0.051,0.051,0.043,0.016,0.000,0.000,0.000,0.012,0.000,0.000,0.278,
 68     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,1.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 69     0.437,0.000,0.000,0.000,0.022,0.000,0.000,0.000,0.294,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.247,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 70     0.611,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.212,0.000,0.000,0.000,0.000,0.000,0.177,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 71     0.006,0.016,0.000,0.029,0.000,0.000,0.019,0.021,0.014,0.000,0.026,0.000,0.109,0.059,0.017,0.000,0.000,0.047,0.088,0.054,0.018,0.000,0.043,0.000,0.065,0.042,0.000,0.328,
 72     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 73     0.522,0.000,0.000,0.000,0.055,0.000,0.000,0.000,0.159,0.000,0.000,0.000,0.000,0.000,0.116,0.000,0.000,0.000,0.000,0.000,0.148,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 74     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 75     0.419,0.000,0.000,0.000,0.016,0.000,0.000,0.000,0.223,0.000,0.000,0.000,0.000,0.000,0.178,0.000,0.000,0.000,0.000,0.000,0.163,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 76     0.261,0.000,0.000,0.070,0.056,0.000,0.000,0.000,0.230,0.000,0.000,0.000,0.009,0.013,0.333,0.000,0.000,0.000,0.000,0.000,0.018,0.000,0.000,0.000,0.000,0.000,0.000,0.011,
 77     0.000,0.007,0.000,0.029,0.000,0.000,0.035,0.008,0.016,0.000,0.122,0.000,0.041,0.038,0.089,0.000,0.000,0.058,0.092,0.126,0.085,0.000,0.000,0.000,0.015,0.026,0.000,0.213,
 78     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 79     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 80     0.680,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.168,0.000,0.000,0.000,0.000,0.000,0.145,0.000,0.000,0.000,0.000,0.000,0.008,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 81     0.202,0.000,0.000,0.000,0.089,0.000,0.000,0.000,0.578,0.000,0.000,0.000,0.000,0.000,0.014,0.000,0.000,0.000,0.000,0.000,0.107,0.000,0.000,0.000,0.011,0.000,0.000,0.000,
 82     0.442,0.000,0.000,0.000,0.014,0.000,0.000,0.000,0.162,0.000,0.000,0.000,0.000,0.000,0.178,0.000,0.000,0.000,0.000,0.025,0.179,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 83     0.008,0.022,0.000,0.041,0.039,0.000,0.052,0.000,0.030,0.000,0.089,0.000,0.087,0.046,0.014,0.000,0.000,0.229,0.019,0.136,0.000,0.000,0.000,0.000,0.011,0.072,0.000,0.103,
 84     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 85     1.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 86     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 87     0.730,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.249,0.000,0.000,0.000,0.000,0.000,0.021,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 88     0.353,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.425,0.000,0.000,0.000,0.000,0.000,0.023,0.000,0.000,0.000,0.000,0.000,0.199,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 89     0.031,0.002,0.000,0.000,0.005,0.037,0.000,0.093,0.056,0.000,0.146,0.000,0.123,0.097,0.107,0.000,0.000,0.000,0.115,0.094,0.024,0.000,0.004,0.000,0.066,0.000,0.000,0.000,
 90     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 91     0.004,0.002,0.000,0.014,0.017,0.004,0.005,0.021,0.051,0.000,0.120,0.000,0.027,0.084,0.028,0.001,0.000,0.073,0.076,0.076,0.002,0.000,0.011,0.000,0.056,0.027,0.000,0.301,
 92     0.083,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.167,0.000,0.000,0.000,0.000,0.000,0.028,0.000,0.000,0.000,0.000,0.000,0.722,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 93     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 94     0.294,0.000,0.000,0.000,0.400,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.176,0.000,0.000,0.000,0.000,0.000,0.129,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 95     0.013,0.002,0.000,0.000,0.006,0.000,0.009,0.036,0.188,0.000,0.036,0.000,0.041,0.094,0.030,0.000,0.000,0.090,0.004,0.034,0.000,0.000,0.000,0.000,0.039,0.002,0.000,0.375,
 96     0.000,0.000,0.000,0.000,0.034,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.966,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 97     0.228,0.000,0.000,0.000,0.190,0.000,0.000,0.000,0.114,0.000,0.000,0.000,0.000,0.000,0.253,0.000,0.000,0.000,0.000,0.000,0.215,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
 98     0.302,0.000,0.000,0.000,0.003,0.000,0.000,0.000,0.487,0.000,0.000,0.000,0.000,0.000,0.196,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.013,0.000,0.000,0.000,
 99     0.013,0.001,0.000,0.026,0.019,0.001,0.014,0.043,0.012,0.000,0.084,0.000,0.028,0.100,0.025,0.001,0.000,0.095,0.047,0.074,0.002,0.000,0.001,0.000,0.031,0.034,0.000,0.352,
100     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
101     0.309,0.000,0.000,0.000,0.076,0.000,0.000,0.000,0.322,0.000,0.004,0.000,0.000,0.000,0.207,0.000,0.000,0.000,0.000,0.000,0.079,0.000,0.000,0.000,0.004,0.000,0.000,0.000,
102     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
103     0.236,0.000,0.000,0.000,0.040,0.000,0.000,0.000,0.509,0.000,0.000,0.000,0.000,0.000,0.152,0.000,0.000,0.000,0.000,0.000,0.063,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
104     0.450,0.006,0.000,0.006,0.083,0.000,0.010,0.000,0.039,0.000,0.010,0.000,0.001,0.013,0.263,0.003,0.000,0.003,0.001,0.009,0.001,0.000,0.000,0.000,0.003,0.012,0.000,0.086,
105     0.010,0.020,0.000,0.003,0.012,0.000,0.002,0.021,0.003,0.000,0.057,0.000,0.057,0.074,0.010,0.000,0.000,0.074,0.098,0.036,0.135,0.000,0.000,0.000,0.017,0.002,0.000,0.369,
106     0.000,0.000,0.000,0.000,0.556,0.000,0.000,0.000,0.111,0.000,0.000,0.000,0.000,0.000,0.000,0.333,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
107     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
108     0.088,0.000,0.000,0.000,0.075,0.000,0.000,0.000,0.392,0.000,0.000,0.000,0.000,0.000,0.209,0.000,0.000,0.000,0.000,0.000,0.189,0.000,0.000,0.000,0.047,0.000,0.000,0.000,
109     0.357,0.000,0.000,0.000,0.100,0.000,0.000,0.000,0.278,0.000,0.000,0.000,0.000,0.000,0.022,0.000,0.000,0.000,0.000,0.000,0.154,0.000,0.000,0.000,0.088,0.000,0.000,0.000,
110     0.216,0.000,0.000,0.000,0.031,0.000,0.000,0.000,0.152,0.000,0.000,0.000,0.000,0.000,0.345,0.000,0.000,0.000,0.000,0.003,0.252,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
111     0.013,0.002,0.000,0.003,0.018,0.000,0.021,0.052,0.033,0.000,0.124,0.000,0.103,0.076,0.010,0.000,0.000,0.048,0.048,0.070,0.072,0.000,0.002,0.000,0.033,0.048,0.000,0.224,
112     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
113     0.971,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.029,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
114     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
115     0.231,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.299,0.000,0.000,0.000,0.000,0.000,0.470,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
116     0.005,0.000,0.000,0.000,0.010,0.000,0.000,0.000,0.282,0.000,0.000,0.000,0.000,0.000,0.077,0.000,0.000,0.000,0.000,0.000,0.492,0.000,0.000,0.000,0.133,0.000,0.000,0.000,
117     0.076,0.000,0.000,0.003,0.015,0.025,0.004,0.086,0.019,0.000,0.109,0.000,0.151,0.074,0.011,0.000,0.000,0.072,0.137,0.101,0.010,0.000,0.006,0.000,0.090,0.011,0.000,0.000,
118     0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
119 };
120 struct Model {
121     static const int N=28;
122     static const int S=26,T=27;
123     db a[N][N];
124     int id(char c) {return tolower(c)-'a';}
125     void train(const db* b) {
126         for(int i=0; i<N; ++i)
127             for(int j=0; j<N; ++j) {
128                 a[i][j]=b[i*N+j];
129                 a[i][j]=a[i][j]>eps?log(a[i][j]):-inf;
130             }
131     }
132     db pred(string s) {
133         db ret=0;
134         ret+=a[S][id(s[0])];
135         for(int i=0; i<(int)s.length()-1; ++i)ret+=a[id(s[i])][id(s[i+1])];
136         ret+=a[id(s[s.length()-1])][T];
137         return ret;
138     }
139 } L[2],R[2];
140 int pred(string s1,string s2) {
141     db l[2];
142     for(int i=0; i<2; ++i)l[i]=L[i].pred(s1)+R[i].pred(s2);
143     return l[0]>l[1]?0:1;
144 }
145 void init() {
146     int tot=28*28;
147     L[0].train(a);
148     R[0].train(a+tot);
149     L[1].train(a+2*tot);
150     R[1].train(a+3*tot);
151 }
152 int main() {
153     //FRER();
154     init();
155     int T;
156     for(cin>>T; T--;) {
157         string s1,s2;
158         cin>>s1>>s2;
159         if(pred(s1,s2)==1)s2+="-san";
160         else s2+="-ssi";
161         printf("%s %s\n",s1.c_str(),s2.c_str());
162     }
163     return 0;
164 }
View Code

这应该是我自己完全独立实现的第一个ML程序了(之前基本都是调库),虽然非常Naive~

posted @ 2022-01-08 17:12  jrltx  阅读(52)  评论(0编辑  收藏  举报