原题链接: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. NoSQL 数据库之MongoDB

    1.MongoDB简介 1.1什么是MongoDB MongoDB 是一个跨平台的,面向文档的数据库,是当前 NoSQL 数据库产品中最热门的一种.它介于关系数据库和非关系数据库之间,是非关系数据库当 ...

  2. SolrCloud下DIH实践

    创建Collection 在/usr/local/solrcloud/solr/server/solr文件夹下创建coreTest文件夹 将/usr/local/solrcloud/solr/serv ...

  3. UVa 1629 DP Cake slicing

    题意: 一块n×m的蛋糕上有若干个樱桃,要求切割若干次以后,每块蛋糕上有且仅有1个樱桃.求最小的切割长度. 分析: d(u, d, l, r)表示切割矩形(u, d, l, r)所需要的最小切割长度. ...

  4. Django Model one

    models :URL---->http://www.cnblogs.com/wupeiqi/p/6216618.html null                     数据库中字段是否可以 ...

  5. Linux IP怎么设置

    最常用的给网卡配置ip的命令为#ifconfig eth0 192.168.0.1 但是,这样重启后又打回原形.要想永久保存,需要 vim /etc/sysconfig/network-scripts ...

  6. wamp搭建的服务器远程无法访问的问题

    最近在一台win2003的服务器上安装配置好了wamp,服务启动正常,服务器本机访问localhost正常,但是我自己的电脑(相对于服务器来说是远程机器)访问时,提示显示You don't have ...

  7. spring boot配置

    spring.application.name=XXXXXserver.port=9515 # health显示down的问题endpoints.health.sensitive= falsemana ...

  8. 21 段实用便捷的 PHP 代码

    PHP 是目前使用最广泛的基于 Web 的编程语言,驱动着数以百万计的网站,其中也包括如 Facebook 等一些大型站点.这里收集了 21 段实用便捷的 PHP 代码摘录,对每种类型的 PHP 开发 ...

  9. [python学习篇][书籍学习][python standrad library][内建函数]之[all,any,basestring,isinstance,bin,bool,@classmethod,@staticmethod,cmp,enumerate

    Python 解释器内置了一些函数,它们总是可用的.这里将它们按字母表顺序列出.     Built-in Functions     abs() divmod() input() open() st ...

  10. linux下 export只能设定临时变量

    今天在调用ABBYY API的时候,需要传递APPID和APPPASSWD给系统环境才能够执行相应的python调用代码. 设置之后,因为写代码自己关掉了terminal,后面直接运行报错,访问权限不 ...