原题链接: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. Head First Python (二)

    if...else... 1 movies = ["The Holy Grail",1975,"Terry Jones & Terry Gilliam" ...

  2. PAT Basic 1076

    1076 Wifi密码 下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请 ...

  3. hbase问题总结

    一.客户端访问hbase时出现no further information 使用java api访问hbase时,一直连不上,查看日志发现以下错误: java.net.ConnectException ...

  4. 多实例设置本地IP访问sql server 数据库

    我们本地有时候有多个数据库版本(^_^..别说了都是泪),都是为了兼容不同版本的数据而安装的! 最近我们需要用IP来访问,就有了这一段折腾的历程. 上图片为我安装的三个不同的版本,一个为sql ser ...

  5. 编译参数-ObjC的说明

    一些第三方库里对系统库的类加了 category , 这时,就需要使用编译参数: -ObjC ,这样第三方库中对系统类作的扩展方法才能在工程中使用. 但是使用 -Objc 后,会产生两个问题: 1 . ...

  6. pg 创建自增id

    CREATE SEQUENCE original_site_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; 先创 ...

  7. onclick跳转到其他页面的几种方式

    如果是本页显示可以直接用location,方法如下: ①onclick="javascript:window.location.href='URL'" ②onclick=" ...

  8. Linux Shell系列教程之(五)Shell字符串

    本文是Linux Shell系列教程的第(五)篇,更多shell教程请看:Linux Shell系列教程 字符串是Shell编程中最常用最有用的数据类型,今天,Linux大学网就为大家介绍一下在She ...

  9. 刷题总结——棘手的操作(bzoj2333)

    题目: 题目背景 SCOI2011 DAY2 T1 题目描述 有 N 个节点,标号从 1 到 N ,这 N 个节点一开始相互不连通.第i个节点的初始权值为 a[i] ,接下来有如下一些操作:U x y ...

  10. P2730 魔板 Magic Squares (搜索)

    题目链接 Solution 这道题,我是用 \(map\) 做的. 具体实现,我们用一个 \(string\) 类型表示任意一种情况. 可以知道,排列最多只有 \(8!\) 个. 然后就是直接的广搜了 ...