Codeforces Round#391 div2

来源:互联网 发布:人工智能 电影免费 编辑:程序博客网 时间:2024/06/06 09:42

A. Gotta Catch Em’ All! (模拟)
http://codeforces.com/problemset/problem/757/A

题意:统计一个字符串中的字母经过重新组合可以构成多少个单词Bulbasaur。

算法:直接统计单个字母出现次数,最后出现次数最少的那个即为答案(a和u出现次数要除以2)。

PS:库函数StrLen的时间复杂度比较高,最好不要放在循环判断里(因为这个超时一个点)。
PPS:比赛时本蒟蒻图样,错把第一个样例当成要统计的单词了,被hack之后才发现。
PPPS:总的来说呢,签到题还要练手速和正确率。

代码:

#include<bits/stdc++.h>#define MAXS 100005using namespace std;char s[MAXS];int main(){    scanf("%s", s);    int len = strlen(s);    int cnt[7]={0,0,0,0,0,0,0};    for (int i=0; i<len; i++)    {        if (s[i] == 'B') cnt[0]++;        if (s[i] == 'u') cnt[1]++;        if (s[i] == 'l') cnt[2]++;        if (s[i] == 'b') cnt[3]++;        if (s[i] == 'a') cnt[4]++;        if (s[i] == 's') cnt[5]++;        if (s[i] == 'r') cnt[6]++;    }    cnt[1] /= 2;    cnt[4] /= 2;    int res = MAXS;    for (int i=0; i<7; i++)        res = min(res, cnt[i]);    printf("%d", res);    return 0;}

B. Bash’s Big Day(数论+贪心)
http://codeforces.com/problemset/problem/757/B

题意:求N个数中最多有几个数的最大公约数不为1。

算法:用一个数组c[i]统计能整除i的数的个数,最后最大的c[i]即为答案。

PS:比赛时最初想着二分答案(毕竟数据范围10^5),后来发现check函数复杂度太高;接着想分解质因数,在网上找了一个号称n^1/4的算法结果第一次提交第11个点超时,严重鄙视;然后直接将10W以内素数打表暴力解决,结果第二次提交第12个点超时;最后在不断尝试中耗掉了漫长的3个小时。。。
PPS:后来看了大牛题解才发现不要分解质因数,一来不需要重复分解,二来公约数也不一定要是素数(虽然从贪心角度而言公约数是素数答案更大,但是这里时间复杂度足够应付了)。事实上,只要枚举2~sqrt(s_i)即可。
PPPS:但是最后的最后还有一个不大不小的错误:循环终止条件我原来写的是j小于sqrt(s_i)。这样是不对的,因为sqrt函数返回值为int本身就做过一次向下取整,这样会有一个可能存在的因子被忽略了。改成j*j小于si就对了。

代码:

#include<bits/stdc++.h>#define MAXN 100005using namespace std;int n, si;int c[MAXN];int main(){    scanf("%d", &n);    memset(c, 0 ,sizeof(c));    for (int i=0; i<n; i++)    {        scanf("%d", &si);        int j = 1;        for (; j*j<si; j++)             if (si % j == 0)            {                c[j]++;                 c[si/j]++;            }        if (j*j == si) c[j]++;    }    int res = 1;    for (int i=2; i<MAXN; i++)          res = max(res, c[i]);    printf("%d\n", res);    return 0;}

C. Felicity is Coming!(排列组合+STL)
http://codeforces.com/contest/757/problem/C

题意:一共有n个gym,第i个gym中有gi个物品。每个物品都属于一种类型且总共有m种类型。变换f:f(x)=y可以将x类型的物品变为y类型的物品。求有多少种变换p:{f1, f2,…, fm}可以使得每个gym中的物品变换前后所有的物品种类数量不变。

算法:f(x)=y且f(y)=x成立当且仅当x和y类型的物品在每个gym种出现的次数相同。假设在每个gym种出现次数相同的类型组成集合s1,s2,…,sk(k<=m),那么答案res=|s1|!|s2|!…|sk|!。强大的C++STL库中有vector容器可以维护这些集合。

PS:看了大牛的题解,第一次体会到STL库功能如此强大。
PPS:比赛时这题直接就放弃了,本蒟蒻的英文水平有待提高。。。

代码:

#include<bits/stdc++.h>#define MAX_M 1000000#define MOD 1000000007using namespace std;vector<int> v[MAX_M];int main(){    int n, m, g, type;    cin >> n >> m;    for(int i = 1; i <= n; i++)    {        cin >> g;        for (int j = 0; j < g; j++)        {            cin >> type;            v[type].push_back(i);        }    }    sort(v + 1, v + 1 + m);    long long card = 1;    long long res = 1;    for(int i = 2 ; i <= m; i++)        if (v[i] == v[i - 1])        {            card++;            res = (res * card) % MOD;        }        else  card = 1;    cout << res;    return 0;}
0 0