Codeforces Round#391 div2

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 100005
using 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 100005
using 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 1000000007
using 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值