原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-andrew-stankevich-contest-22-asc-22-en.pdf

题意

这是一个过滤垃圾邮件的算法,叫贝叶斯算法。这个算法的第一步是训练过程,通过人工给定的邮件,来确定每个词语在垃圾邮件中的概率和在普通邮件的概率。然后通过贝叶斯公式来计算每个邮件是否为垃圾邮件。具体过程可以看题,或者维基百科。

题解

模拟题目的过程即可,不过要注意的是,为了避免超时,必须哈希,使用 最小表示来记录字符串。

代码

//#include<iostream>
#include<cstring>
#include<fstream>
#include<vector>
#include<map>
#include<algorithm>
#include<string>
#include<set>
#include<cmath>
#include<queue>
#define eps 1e-10
#define MAX_N 1234
#define Pr 131
#define mod 1000000009
using namespace std; typedef long long ll; int s,g,n,t;
string sp[MAX_N];
string go[MAX_N];
string ma[MAX_N]; set<ll> spam[MAX_N];
set<ll> good[MAX_N];
set<ll> mail[MAX_N]; set<ll> allWord; string bankLine; map<ll, double> wordIsSpam;
map<ll, double> wordIsGood; double pSpam;
double pGood; ll Hash(string ss) {
ll tmp = Pr;
ll res = ;
for (auto c:ss) {
res = (res + c * tmp) % mod;
tmp = (tmp * Pr) % mod;
}
return res;
} string changeToSmall(string ss) {
string res = "";
for (auto c:ss) {
if (c <= 'Z' && c >= 'A')c = c - 'A' + 'a';
res = res + c;
}
return res;
} bool isAl(char c) {
if (c <= 'Z' && c >= 'A')return true;
return (c <= 'z' && 'a' <= c);
} void divi(string v[],set<ll> G[],int x) {
for (int i = ; i < x; i++) {
int p = ;
while ((!isAl(v[i][p])) && p < v[i].length())p++;
bool flag = true;
for (int j = p; j < v[i].length(); j++) {
if ((!isAl(v[i][j])) && flag) {
flag = false;
string tmp;
tmp.assign(v[i].begin() + p, v[i].begin() + j);
tmp = changeToSmall(tmp);
allWord.insert(Hash(tmp));
G[i].insert(Hash(tmp));
}
else if (isAl(v[i][j]) && flag == false) {
p = j;
flag = true;
}
}
}
} double divide(double a,double b) {
if (fabs(b)<eps)return ;
return a / b;
} double P(ll word) {
double ws, wg; if (wordIsSpam.find(word) == wordIsSpam.end())ws = ;
else ws = wordIsSpam[word]; if (wordIsGood.find(word) == wordIsGood.end())wg = ;
else wg = wordIsGood[word]; return divide(ws * pSpam, ws * pSpam + wg * pGood);
} int main() {
ifstream cin("spam.in");
ofstream cout("spam.out");
cin.sync_with_stdio(false);
cin >> s >> g >> n >> t;
pSpam = divide(s, s + g);
pGood = divide(g, s + g);
getline(cin, bankLine);
for (int i = ; i < s; i++) {
getline(cin, sp[i]);
sp[i] = sp[i] + " ";
}
for (int i = ; i < g; i++) {
getline(cin, go[i]);
go[i] = go[i] + " ";
}
for (int i = ; i < n; i++) {
getline(cin, ma[i]);
ma[i] = ma[i] + " ";
}
divi(sp, spam, s);
divi(go, good, g);
divi(ma, mail, n); for (auto word:allWord) {
int cnt = ;
for (int i = ; i < s; i++)
if (spam[i].find(word) != spam[i].end())cnt++;
wordIsSpam[word] = divide(cnt, s);
cnt = ;
for (int i = ; i < g; i++)
if (good[i].find(word) != good[i].end())cnt++;
wordIsGood[word] = divide(cnt, g);
}
for (int i = ; i < n; i++) {
double ans = ;
for (auto word:mail[i]) {
double p = P(word);
//cout<<word<<": "<<p<<endl;
if (p > 0.5 || fabs(p - 0.5) < eps)ans++;
}
if (ans * / mail[i].size() < t)cout << "good" << endl;
else cout << "spam" << endl;
}
return ;
}

Codeforces Gym 100338B Spam Filter 字符串哈希+贝叶斯公式的更多相关文章

  1. codeforces Gym 100338F Spam Filter 垃圾邮件过滤器(模拟,实现)

    阅读题, 概要:给出垃圾邮件和非垃圾邮件的集合,然后按照题目给出的贝叶斯公式计算概率一封邮件是垃圾邮件的概率. 逐个单词判断,将公式化简一下就是在垃圾邮件中出现的次数和在总次数的比值,大于二分之一就算 ...

  2. 【CodeForces】961 F. k-substrings 字符串哈希+二分

    [题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} ...

  3. codeforces gym 100286 I iSharp (字符串模拟)

    题目链接 给定一个字符串.输入是int& a*[]&, b, c*; 输出是 int&&[]* a;int& b;int&* c; 输入格式里逗号后面一 ...

  4. codeforces gym 101164 K Cutting 字符串hash

    题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...

  5. Codeforces Gym 100338B Geometry Problem 计算几何

    Problem B. Geometry ProblemTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudg ...

  6. Codeforces Round #543 (Div. 2) F dp + 二分 + 字符串哈希

    https://codeforces.com/contest/1121/problem/F 题意 给你一个有n(<=5000)个字符的串,有两种压缩字符的方法: 1. 压缩单一字符,代价为a 2 ...

  7. CodeForces Gym 100213F Counterfeit Money

    CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...

  8. HDU 1880 魔咒词典(字符串哈希)

    题目链接 Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一 ...

  9. 洛谷P3370 【模板】字符串哈希

    P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...

随机推荐

  1. proc_info_list

    内核中每种处理器架构抽象为一个proc_info_list结构体,在arch/arm/include/asm/procinfo.h中定义, struct proc_info_list { unsign ...

  2. Spring boot 中Spring data JPA的应用(一)

    最近一直在研究Spring Boot,今天为大家介绍下Spring Data JPA在Spring Boot中的应用,如有错误,欢迎大家指正. 先解释下什么是JPA JPA就是一个基于O/R映射的标准 ...

  3. vss安装注意点

    一:装好IIS 二:win7用管理员权限打开 server configuration 才能打上勾 三:用计算机名,不要用 Ip地址

  4. jenkins 之 Android 打包及上传至蒲公英

    准备条件 iMAC,非必须(如果是 安卓 和 苹果 可以在同一台电脑上打包则要 Mac OS 系统的电脑,如果是只是给安卓打包 windows 电脑也是可以的, window 下 需要把 ls 换成 ...

  5. python 获得列表中每个元素出现次数的最快方法

    import collections import numpy as np import random import time def list_to_dict(lst): dic = {} for ...

  6. perl第三章 列表和数组

    访问数组中的元素    $fred[0]   $fred[1] $number=2.75; print $fred[$number-1]  结果就是print $fred[1] 特殊的数组索引1.对索 ...

  7. 使用 Rails Webpacker 安裝 Foundation 6

    動機 由於 foundation-rails 6.4.1 版本有個 Issue 目前還沒合併.加上 Rails 已經支援了 webpack 2.x.這篇文章純粹紀錄另外一種做法. 準備 開始使用之前需 ...

  8. csa Round #66 (Div. 2 only)

    csa66 Risk Rolls Time limit: 1000 msMemory limit: 256 MB   Alena and Boris are playing Risk today. W ...

  9. javascript学习笔记 - 引用类型 Function

    五 Function类型 每个函数都时Function类型的实例.函数也是对象. 声明函数: function func_name () {} //javascript解析器会在程序执行时率先读取函数 ...

  10. 【Luogu】P2598狼和羊的故事(最小割转最大流)

    题目链接 最小割水题.入点向白点连边,白点向白点.黑点和空点连边,空点向空点和黑点连边,黑点向黑点和汇点连边.然后跑最大流即可. 话说Fd最近怎么光做水题啊……一点用都没有……qwq 我太菜了,做完一 ...